下面來了解spring事務實現的幾個關鍵類
PlatformTransactionManager
TransactionDefinition
TransactionStatus
3.1 PlatformTransactionManager是spring事物框架的一個核心接口, 雖然說應用可以直接使用,但是應用一般是通過TransactionTemplate或者通過aop聲明式事務方式來使用,下面我們來看一下這個接口的定義
Public interface PlatformTransactionManager{
//返回當前事務,或者開啓一個事物
TransactionStatus getTransaction(TransactionDefinition definition);
//事務提交
voidcommit(TransactionStatus status);
//事物回滾
voidrollback(TransactionStatus status);
}
大家應該很容易看出來這個接口的使用方式
1) TransactionStatus status = transactionManager.getTransaction(definition);
根據事物的定義開啓或者返回當前事務
2) 執行本地數據庫crud操作, 並根據執行結果設置事物狀態
3) 根據事物狀態回滾或者提交
transactionManager.commit(status);
transactionManager.rollback(status);
3.2 TransactionDefinition
主要定義事務的隔離級別,傳播級別,事務超時時間以及是否只讀事務
下面我們來看幾種事務配置片段:
1) <bean id="test"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置事務管理器 -->
<property name="transactionManager" ref="transactionManager" />
<property name="target" ref="testTarget" />
<property name="proxyInterfaces" value="hongwei.quhw.Test" />
<!-- 配置事務屬性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
2) <bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<!-- 配置事務屬性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
3) <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
4) @Transactional(propagation=Propagation.REQUIRED)
public class TestImpl implement Test{
}
無論你能在網上找到的對事務屬性的配置方式最終都會轉換爲TransactionDefinition的實現類,在PlatformTransactionManager事務管理器根據事務定義來開啓事物
3.3 TransactionStatus
1) 有前面的描述事務管理器PlatformTransactionManager開啓事務的方法getTransaction中獲取事務狀態對象TransactionStatus,在開啓事務方法getTransaction中判斷需不需要開啓一個新的事務,如果開啓新的事務那麼isNewTransaction()值爲true,如果不開啓新的事務isNewTransaction()的值爲false
2) 根據執行業務邏輯結果判斷是否需要回滾事務,需要回滾調用方法setRollbackOnly(),這樣isRollbackOnly()爲true, 否則沒有調用isRollbackOnly()爲false代表不需要回滾
3)(1) 根據isRollbackOnly()值來決定調PlatformTransactionManager的commit或者rollback方法;
(2) 根據isNewTransaction()值,如果爲true的代表需要真正執行commit或者rollback操作; 若果爲false不做數據庫層面的commit或者rollback,做一些業務層面的回調處理。
事物同步管理器
3.4 DatasourceTransactionManager
下面以我們常使用的,基於java數據源標準接口Datasource操作的事物管理器DatasourceTransactionManager爲例來具體講解spring的事務流程。
AbstractPlatformTransactionManager實現了事務管理器接口,定義了事務管理的流程模板封裝了事務管理的公共操作
3.4.1獲取事務流程getTransaction(definition)
1) 調抽象方法transaction =doGetTransaction(), 獲取代表事務的對象,這個方法在DatasourceTransactionManager中會構建一個DataSourceTransactionObject對象並根據數據源Datasource到當前線程獲取數據庫連接封裝對象ConnectionHolder(第一次開啓就爲null)設置到對象中。
由上描述知道我們獲取的事物對象有可能是沒有獲取數據連接開始事務。
2) 判斷如果沒傳入TransactionDefinition對象的話,構建一個默認的事務定義對象
3) isExistingTransaction(transaction),判讀有沒有開啓數據庫鏈接,事務有沒有激活。如果已開啓且事務已經激活, 那麼根據事務的傳播級別處理事務狀態一般會構建TransactionStatus對象newTransaction屬性設置爲false,在通過事務同步器把事務狀態同步到當前線程
這裏結束流程,返回事務狀態
4) 事務超時時間的判斷
5) 構建TransactionStatus對象newTransaction屬性設置爲true
開啓事調doBegin方法, 在DatasourceTransactionManager中具體實現爲從dataSource獲取數據庫連接,將數據連接autoCommit設置爲false, 激活事務,將connectionHodler連接資源綁定到線程變量中
6) 在過事務同步器把事務狀態同步到當前線程
3.4.2 commit(TransactionStatus)
1) 根據事務狀態,判斷事務是否應經結束
2) 根據事務狀態判斷是否需要回滾,回滾走回滾流程
3) processCommit(status) 執行事務提交,下面我們先用僞代碼示例下:
try {
try {
triggerBeforeCommit(status);
} finally {
triggerBeforeCompletion(status);
}
doCommit(status);
try {
triggerAfterCommit(status);
} finally {
triggerAfterCompletion(status);
}
} finally {
cleanupAfterCompletion(status);
}
doCommit是真正的數據庫提交DatasourceTransactionManager中的實現爲connection.commit()
在做doCommit前後都提供了回調接口供業務擴展
triggerBeforeCommit做一些像O/R mapping框架的flush操作並不是真正的事務提交
triggerBeforeCompletion在triggerBeforeCommit之後做一些資源清理工作,triggerBeforeCommit拋異常也執行
triggerAfterCommit在事務真正提交之後做一些操作如確認消息發送郵件等等
triggerAfterCompletion無論事務提交成功與否都要做一些資源的清理工作
cleanupAfterCompletion最後對事務同步器做一些清理工作
3.4.3 rollback(status) 回滾事務
1) 根據事務狀態,判斷事務是否應經結束
2) processRollback(status)執行事務回滾,如下類似僞代碼:
try {
triggerBeforeCompletion(status);
doRollback(status);
triggerAfterCompletion(status);
} finally {
cleanupAfterCompletion(status);
}
3.4.4如上事務的提交回滾操作的前後都提供了回調接口,spring通過事務同步器的註冊與回調機制來保證業務在事務提交前後插入業務, xts二階段的實現也利用了這個機制。
TransactionSynchronizationUtils工具類銜接了上面的回調入口和事務同步器管理類TransactionSynchronizationManager
TransactionSynchronizationManager.registerSynchronization方法用來向當前線程註冊實現了TransactionSynchronization接口的事務同步器,它定義了一些回調方法業務實現
public interface TransactionSynchronization{
void beforeCommit(boolean readOnly);
void beforeCompletion();
void afterCommit();
void afterCompletion(int status);
……等等
}
自此我們基本介紹了spring事務的內核設計及流程。
我們常用spring事務模板TransactionTemplate就是利用上面介紹的核心類型封裝了事務流程,通過TransactionCallback接口專注業務邏輯。
Spring事務的還一大亮點就是它的聲明式事務的實現,spring的聲明式事務是springaop的一個很好的示例,很多同學在工作很長一段時間都沒有業務場景要求他們寫一個aop也沒有很好的理解清楚springaop的使用場景,不妨看看spring聲明式事務的實現,對於spring聲明式事務實現springaop原理這裏就不在展開了。