Spring Transaction(spring事務)源碼簡析

核心接口:PlatformTransactionManager.java 還有其抽象類AbstractPlatformTransactionManager:
簡述
Spring事務基礎結構的中心接口。
代碼詳解
public interface PlatformTransactionManager {
    commit();
    rollback();
    beginTransaction();
}
 
AbstractPlatformTransactionManager繼承了PlatformTransactionManager接口
簡述
    實現PlatformTransactionManager基類的標準事務工作流,作爲基礎事務管理平臺的基礎如JtaTransactionManager。
    這個基礎類提供瞭如下工作流處理:
    * 確定是否有事務
    * 應用對應的spring事務傳播等級
    * 必要時對事務進行暫停(suspends)和恢復(resumes)
    * 提交時檢查rollback-only標記(出錯只能回滾)
    * 觸發同步回調註冊(如果事務同步是激活)
    子類繼承當前抽象類需要實現begin, suspend, resume, commit, rollback.方法
    事務同步是一種通用機制,用於註冊在事務完成時調用的回調。
    這個數據的內部訪問主要用來支持運行在JTA事務的JDBC、Hibernate、JPA等,允許事務週期中重用相同會話的事務如Hibernate事務。
    可序列化,允許序列化事務策略以及攜帶事務攔截器的代理。這取決於子類是否想使他們狀態可序列化,就應該實現Serializable接口標識和private 的readObject方法。
注:什麼是JTA,主要用於處理分佈式事務,實現兩段式提交協議(ready、commit階段)。
代碼詳解
  • 先看幾個概念:
  • + 事務同步:兩個事務操作相同表,後一個需要等待前一個
  • + empty事務:未找到含義,猜測是事務中無任何操作。
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
  //設置事務同步(默認)
    public static final int SYNCHRONIZATION_ALWAYS = 0;
    //設置事務同步(非空事務下才會才生效)
    public static final int SYNCHRONIZATION_ON_ACTUAL_TRANSACTION = 1;
     //設置事務不同步
    public static final int SYNCHRONIZATION_NEVER = 2;
    //AbstractPlatformTransactionManager的常量實例
    private static final Constants constants = new Constants(AbstractPlatformTransactionManager.class);
     //打log用的
    protected transient Log logger = LogFactory.getLog(getClass());
     //將事務同步級別默認設置爲SYNCHRONIZATION_ALWAYS   --對應get/set方法
    private int transactionSynchronization = SYNCHRONIZATION_ALWAYS;
    //初始化默認超時時間爲-1    --對應get/set方法
    private int defaultTimeout = TransactionDefinition.TIMEOUT_DEFAULT;
    //初始化默認不允許嵌套事務    --對應get/set方法
    private boolean nestedTransactionAllowed = false;
     //初始化默認在參與前不驗證已存在的事務    --對應get/set方法
    private boolean validateExistingTransaction = false;
    //初始化默認事務失敗後標記爲rollback-only    --對應get/set方法
    private boolean globalRollbackOnParticipationFailure = true;
    //初始化默認事務失敗後,不會盡早標記未rollback-readonly    --對應get/set方法
    private boolean failEarlyOnGlobalRollbackOnly = false;
    //初始化默認commit時候後不回滾    --對應get/set方法
    private boolean rollbackOnCommitFailure = false;
    ................................................................................................
     //根據傳播等級獲取對應的事務
    public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
        //doGetTransaction()是個鉤子方法,由其子類進行實現如JtaTransactionManager、HibernateTransactionManager
        Object transaction = doGetTransaction();
        ....................
    }
    ..rollback()...
    ..commit()...
    ..............
}
 

然後在IDEA按 Ctrl+H 可以看到當前AbstractPlatformTransactionManager的上級繼承體系:
 
 

然後看到DataSourceTransactionManager.java(繼承AbstractPlatformTransactionManager):
 
    
TransactionDefinition.java:定義了事務傳播性、隔離性等:
public interface TransactionDefinition {
int PROPAGATION_REQUIRED = 0;
。。。。。。。。。。。。。
 
 
 
jdbctemplate封裝過程:
 
 
下面再來簡單看一下DataSourceTransactionManager的代碼:
org.springframework.jdbc.datasource.DataSourceTransactionManager:
 
 
DataSourceTransactionManager繼承了AbstractPlatformTransactionManager抽象接口。並且重寫了 doGetTransaction()方法如下:
@Override
protected Object doGetTransaction() {
    DataSourceTransactionObject txObject = new DataSourceTransactionObject();
    txObject.setSavepointAllowed(isNestedTransactionAllowed());  //isNestedTransactionAllowed()在當前實例初始化時被設置成true
    ConnectionHolder conHolder =
        (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
    txObject.setConnectionHolder(conHolder, false);
    return txObject;
}
 
1 其中doGetTransaction()是實現了模板方法模式,是AbstractPlatformTransactionManager的鉤子,其在AbstractPlatformTransactionManager的位置如下:
 
 
 
由doGetTransaction()的
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
 
 
主要涉及到的參數設置爲"連接保持者對象(newConnectionHolder)"、"事務自動提交(mustRestoreAutoCommit)"、"是否可回滾(isRollbackOnly)"
 
從上面我們看到這設置了"連接保持者對象",也就doGetTransaction()下面的設置代碼如下:
ConnectionHolder conHolder =
    (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
txObject.setConnectionHolder(conHolder, false);
 
但什麼是"連接保持者對象"?
 
 
直接實例化DataSourceTransactionManager如下:
    public DataSourceTransactionManager() { setNestedTransactionAllowed(true); }
以上代碼會設置nestedTransactionAllowed = true
然後nestedTransactionAllowed在兩個地方用到如下:
1) 獲取事務的時候設置保存點
 
 
2)事務傳播級別爲PROPAGATION_NESTED時,必須爲true判斷校驗
 
 
 
2 往下看DataSourceTransactionManager#isExistingTransaction(Object transaction)
@Override
protected boolean isExistingTransaction(Object transaction) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    // 判斷連接保持者是否爲空或是否開啓了事務
    return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());
}
 
 
這裏設置自動提交由spring控制
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章