-
先看幾個概念:
-
+ 事務同步:兩個事務操作相同表,後一個需要等待前一個
-
+ empty事務:未找到含義,猜測是事務中無任何操作。
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階段)。
代碼詳解
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)"
ConnectionHolder參考鏈接: https://www.cnblogs.com/davenkin/archive/2013/02/23/java-tranaction-4.html
從上面我們看到這設置了"連接保持者對象",也就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控制
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.