spring 事務(wù)詳解
來源:程序員人生 發(fā)布時(shí)間:2016-12-15 10:11:22 閱讀次數(shù):4649次
1、甚么是事務(wù)
事務(wù)是1系列的動(dòng)作,它們綜合在1起才是1個(gè)完全的工作單元,這些動(dòng)作必須全部完成,如果有1個(gè)失敗的話,那末事務(wù)就會(huì)回滾到最開始的狀態(tài)。事務(wù)有4個(gè)特性ACID:
- 原子性(Atomicity):事務(wù)是1個(gè)原子操作,由1系列動(dòng)作組成。事務(wù)的原子性確保動(dòng)作要末全部完成,要末完全不起作用。
- 1致性(Consistency):1旦事務(wù)完成(不管成功還是失敗),系統(tǒng)必須確保它所建模的業(yè)務(wù)處于1致的狀態(tài),而不會(huì)是部份完成部份失敗
- 隔離性(Isolation):可能有許多事務(wù)會(huì)同時(shí)處理相同的數(shù)據(jù),因此每一個(gè)事務(wù)都應(yīng)當(dāng)與其他事務(wù)隔離開來,避免數(shù)據(jù)破壞。
- 持久性(Durability):1旦事務(wù)完成,不管產(chǎn)生甚么系統(tǒng)毛病,它的結(jié)果都不應(yīng)當(dāng)遭到影響。通常情況下,事務(wù)的結(jié)果被寫到持久化存儲(chǔ)器中。
2、spring事務(wù)管理器
Spring其實(shí)不直接收理事務(wù),而是提供了多種事務(wù)管理器。Spring事務(wù)管理器的接口是org.springframework.transaction.PlatformTransactionManager,通過這個(gè)接口,Spring為各個(gè)平臺(tái)如JDBC、Hibernate等都提供了對(duì)應(yīng)的事務(wù)管理器,但是具體的實(shí)現(xiàn)就是各個(gè)平臺(tái)自己的事情了。接口中有3個(gè)方法
public interface PlatformTransactionManager {
//根據(jù)事務(wù)定義TransactionDefinition,獲得事務(wù)
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
//提交事務(wù)
void commit(TransactionStatus status) throws TransactionException;
//回滾事務(wù)
void rollback(TransactionStatus status) throws TransactionException;
}
其中,TransactionDefinition是事務(wù)的1些基礎(chǔ)信息,如超時(shí)時(shí)間,隔離級(jí)別,傳播特性等;TransactionStatus是事務(wù)的狀態(tài),如是否是1個(gè)新事務(wù),是不是被標(biāo)記為回滾等。Spring針對(duì)不同的ORM提供的事務(wù)管理器,都是集成自AbstractPlatformTransactionManager,而AbstractPlatformTransactionManager又實(shí)現(xiàn)了PlatformTransactionManager。
2.1 JDBC、Mybatis和ibatis事務(wù)管理器
如果利用程序中直接使用JDBC來進(jìn)行持久化,需要配置JDBC事務(wù)管理器DataSourceTransactionManager,通過DataSource獲得到java.sql.Connection來管理事務(wù),調(diào)用連接的commit()方法來提交事務(wù),一樣,事務(wù)失敗則通過調(diào)用rollback()方法進(jìn)行回滾。
-
<!-- (事務(wù)管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
2.2 Hibernate事務(wù)管理器 -
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
2.3 JPA事務(wù)管理器 -
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
通過entityManagerFactory屬性指定需要事務(wù)管理的javax.persistence.EntityManagerFactory對(duì)象。還需要為entityManagerFactory對(duì)象指定jpaDialect屬性,該屬性所對(duì)應(yīng)的對(duì)象指定了如何獲得連接對(duì)象、開啟事務(wù)、關(guān)閉事務(wù)等事務(wù)管理相干的行動(dòng)。
-
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
……
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
2.4 Java散布式事務(wù)管理器JTA -
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction" ref="jotm" />
</bean>
-
<!-- JOTM實(shí)例 -->
<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean">
<property name="defaultTimeout" value="500000"/>
</bean>
散布式事務(wù)通常是指多個(gè)數(shù)據(jù)源之間的實(shí)物,在tomcat下,是沒有散布式事務(wù)的,不過可以借助于第3方軟件jotm(Java Open Transaction Manager )和AtomikosTransactionsEssentials實(shí)現(xiàn)。
2.5 JDO事務(wù)管理器
-
<bean id="txManager" class="org.springframework.orm.jdo.JdoTransactionManager">
<property name="persistenceManagerFactory" ref="persistenceManagerFactory"/>
</bean>
通過persistenceManagerFactory屬性指定需要事務(wù)管理的javax.jdo.PersistenceManagerFactory對(duì)象。
具體可參考:http://hhhk.iteye.com/blog/2082714
3、Spring事務(wù)的特性
1、事務(wù)的傳播行動(dòng)
所謂事務(wù)的傳播行動(dòng)是指,如果在開始當(dāng)前事務(wù)之前,1個(gè)事務(wù)上下文已存在,此時(shí)有若干選項(xiàng)可以指定1個(gè)事務(wù)性方法的履行行動(dòng)。在TransactionDefinition定義中包括了以下幾個(gè)表示傳播行動(dòng)的常量:
-
TransactionDefinition.PROPAGATION_NESTED:如果當(dāng)前存在事務(wù),則創(chuàng)建1個(gè)事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來運(yùn)行;如果當(dāng)前沒有事務(wù),則該取值等價(jià)于TransactionDefinition.PROPAGATION_REQUIRED。
TransactionDefinition.PROPAGATION_MANDATORY:如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則拋出異常。
TransactionDefinition.PROPAGATION_NEVER:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異常。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。
TransactionDefinition.PROPAGATION_SUPPORTS:如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則以非事務(wù)的方式繼續(xù)運(yùn)行。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:創(chuàng)建1個(gè)新的事務(wù),如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。
TransactionDefinition.PROPAGATION_REQUIRED:如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則創(chuàng)建1個(gè)新的事務(wù)。這是默許值。
2、事務(wù)的隔離級(jí)別
隔離級(jí)別是指若干個(gè)并發(fā)的事務(wù)之間的隔離程度。TransactionDefinition 接口中定義了5個(gè)表示隔離級(jí)別的常量:
-
TransactionDefinition.ISOLATION_READ_UNCOMMITTED:該隔離級(jí)別表示1個(gè)事務(wù)可以讀取另外一個(gè)事務(wù)修改但還沒有提交的數(shù)據(jù)。該級(jí)別不能避免臟讀,不可重復(fù)讀和幻讀,因此很少使用該隔離級(jí)別。
TransactionDefinition.ISOLATION_READ_COMMITTED:該隔離級(jí)別表示1個(gè)事務(wù)只能讀取另外一個(gè)事務(wù)已提交的數(shù)據(jù)。該級(jí)別可以避免臟讀,這也是大多數(shù)情況下的推薦值。
TransactionDefinition.ISOLATION_REPEATABLE_READ:該隔離級(jí)別表示1個(gè)事務(wù)在全部進(jìn)程中可以屢次重復(fù)履行某個(gè)查詢,并且每次返回的記錄都相同。該級(jí)別可以避免臟讀和不可重復(fù)讀。
TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事務(wù)順次逐一履行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾,也就是說,該級(jí)別可以避免臟讀、不可重復(fù)讀和幻讀。但是這將嚴(yán)重影響程序的性能。通常情況下也不會(huì)用到該級(jí)別。
3、只讀屬性
事務(wù)的第3個(gè)特性是它是不是為只讀事務(wù)。如果事務(wù)只對(duì)后真?zhèn)€數(shù)據(jù)庫進(jìn)行該操作,數(shù)據(jù)庫可以利用事務(wù)的只讀特性來進(jìn)行1些特定的優(yōu)化。
4、事務(wù)超時(shí)
由于事務(wù)可能觸及對(duì)后端數(shù)據(jù)庫的鎖定,所以長(zhǎng)時(shí)間的事務(wù)會(huì)沒必要要的占用數(shù)據(jù)庫資源。事務(wù)超時(shí)就是事務(wù)的1個(gè)定時(shí)器,在特定時(shí)間內(nèi)事務(wù)如果沒有履行終了,那末就會(huì)自動(dòng)回滾,而不是1直等待其結(jié)束。
5、回滾規(guī)則
唆使spring事務(wù)管理器回滾1個(gè)事務(wù)的推薦方法是在當(dāng)前事務(wù)的上下文內(nèi)拋出異常。spring事務(wù)管理器會(huì)捕捉任何未處理的異常,然后根據(jù)規(guī)則決定是不是回滾拋出異常的事務(wù)。默許配置下,spring只有在拋出的異常為運(yùn)行時(shí)unchecked異常時(shí)才回滾該事務(wù),也就是拋出的異常為RuntimeException的子類(Errors也會(huì)致使事務(wù)回滾),而拋出checked異常則不會(huì)致使事務(wù)回滾。可以明確的配置在拋出那些異常時(shí)回滾事務(wù),包括checked異常。也能夠明肯定義那些異常拋出時(shí)不回滾事務(wù)。還可以編程性的通過setRollbackOnly()方法來唆使1個(gè)事務(wù)必須回滾,在調(diào)用完setRollbackOnly()后你所能履行的唯1操作就是回滾。
6、事務(wù)狀態(tài)
public interface TransactionStatus{
boolean isNewTransaction(); // 是不是是新的事物
boolean hasSavepoint(); // 是不是有恢復(fù)點(diǎn)
void setRollbackOnly(); // 設(shè)置為只回滾
boolean isRollbackOnly(); // 是不是為只回滾
boolean isCompleted; // 是不是已完成
}
4、Spring支持的事務(wù)管理
Spring提供了對(duì)編程式事務(wù)和聲明式事務(wù)的支持,編程式事務(wù)允許用戶在代碼中精肯定義事務(wù)的邊界,而聲明式事務(wù)(基于AOP)有助于用戶將操作與事務(wù)規(guī)則進(jìn)行解耦。
Spring配置文件中關(guān)于事務(wù)配置總是由3個(gè)組成部份,分別是DataSource、TransactionManager和代理機(jī)制這3部份,不管哪一種配置方式,1般變化的只是代理機(jī)制這部份。DataSource、TransactionManager這兩部份只是會(huì)根據(jù)數(shù)據(jù)訪問方式有所變化,比如使用Hibernate進(jìn)行數(shù)據(jù)訪問時(shí),DataSource實(shí)際為SessionFactory,TransactionManager的實(shí)現(xiàn)為HibernateTransactionManager。
1、編程式事務(wù)
Spring提供兩種方式的編程式事務(wù)管理,分別是:使用TransactionTemplate和直接使用PlatformTransactionManager。
1)采取TransactionTemplate和采取其他Spring模板,如JdbcTempalte和HibernateTemplate是1樣的方法,它使用回調(diào)方法,把利用程序從處理獲得和釋放資源中擺脫出來。TransactionTemplate是線程安全的。
-
<!-- JDBC事務(wù)管理器 注意:事務(wù)管理器傳的參數(shù)是數(shù)據(jù)源-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager" scope="singleton">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<!-- 聲明事務(wù)模板 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
</bean>
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
}
else {
TransactionStatus status = this.transactionManager.getTransaction(this);
T result;
try {
result = action.doInTransaction(status);
}
catch (RuntimeException ex) {
// Transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
catch (Error err) {
// Transactional code threw error -> rollback
rollbackOnException(status, err);
throw err;
}
catch (Exception ex) {
// Transactional code threw unexpected exception -> rollback
rollbackOnException(status, ex);
throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
}
this.transactionManager.commit(status);
return result;
}
}
可以看到transactionTemplate 的履行是在execute中的,所以 -
TransactionTemplate tt = new TransactionTemplate(); // 新建1個(gè)TransactionTemplate
Object result = tt.execute(
new TransactionCallback(){
public Object doTransaction(TransactionStatus status){
updateOperation();
return resultOfUpdateOperation();
}
}); // 履行execute方法進(jìn)行事務(wù)管理
2)使用PlatformTransactionManager
2、聲明式事務(wù)管理
1)利用aop配置
-
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="interceptorPointCuts" expression="execution(* com.bluesky.spring.dao.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" />
</aop:config>
2)聲明式注解事務(wù) -
<!-- 注解方式配置事物 -->
<tx:annotation-driven transaction-manager="transactionManager" />
3)使用攔截器 -
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<!-- 配置事務(wù)屬性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Dao</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)