SpringAOP[2]-@Transaction原理
參考:Spring事務實現原理 - insaneXs - 部落格園 (cnblogs.com)
一、事務前置
JDBC原生事務管理
// 獲取mysql資料庫連線 Connection conn = DriverManager.getConnection("xxxx"); conn.setAutoCommit(false); statement = conn.createStatement(); // 執行sql,返回結果集 resultSet = statement.executeQuery("xxxx"); //提交 conn.commit(); //conn.rollback();//回滾
Spring則將這個過程進行了深度封裝,最基礎原理還是這個
Spring事務API
Spring提供了很多關於事務的API。但是最為基本的就是PlatformTransactionManager
、TransactionDefintion
和TransactionStatus
。
事務管理器——PlatformTransactionManager
PlatformTransactionManager
是事務管理器的頂層介面。事務的管理是受限於具體的資料來源的(例如,JDBC對應的事務管理器就是DatasourceTransactionManager
),因此PlatformTransactionManager
只規定了事務的基本操作:建立事務,提交事物和回滾事務。
public interface PlatformTransactionManager extends TransactionManager { // 根據事務定義獲取事務/開啟事務 TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException; // 事務提交 void commit(TransactionStatus status) throws TransactionException;// 事務回滾 void rollback(TransactionStatus status) throws TransactionException; }
同時為了簡化事務管理器的實現,Spring提供了一個抽象類AbstractPlatformTransactionManager
,規定了事務管理器的基本框架,僅將依賴於具體平臺的特性作為抽象方法留給子類實現。
事務狀態——TransactionStatus
事務狀態是我對TransactionStatus
這個類的直譯。其實我覺得這個類可以直接當作事務的超集來看(包含了事務物件,並且儲存了事務的狀態)。PlatformTransactionManager.getTransaction()
時建立的也正是這個物件。
這個物件的方法都和事務狀態相關:
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable { // 當前事務是否存在儲存點 boolean hasSavepoint(); // 重新整理資料, 和底層資料庫是否支援有關, 略 @Override void flush(); }
可以看到TransactionStatus 繼承了TransactionExecution 和SavepointManager ,前者提供當前事務狀態訪問,後者提供儲存點的訪問
public interface TransactionExecution { // 是否是一個新事務, 是否在一個事務內部 boolean isNewTransaction(); // 觸發回滾, 異常會回滾, 設定了這個標誌位也會回滾 void setRollbackOnly(); boolean isRollbackOnly(); // 事務是否已結束, 已提交 || 已回滾 boolean isCompleted(); }
public interface SavepointManager { // 建立儲存點 Object createSavepoint() throws TransactionException; // 回滾到儲存點 void rollbackToSavepoint(Object savepoint) throws TransactionException; // 釋放儲存點 void releaseSavepoint(Object savepoint) throws TransactionException; }
事務屬性的定義——TransactionDefinition
大致只需知道:傳播行為 + 隔離級別
public interface TransactionDefinition { // 預設事務傳播行為, 沒有事務新建事務, 有事務在事務內執行 default int getPropagationBehavior() { return PROPAGATION_REQUIRED; } // 預設事務隔離級別 default int getIsolationLevel() { return ISOLATION_DEFAULT; } // 超時時間(-1) default int getTimeout() { return TIMEOUT_DEFAULT; } // 是否只讀事務, 這個也是要看資料庫是否支援 default boolean isReadOnly() { return false; } @Nullable default String getName() { return null; } // Static builder methods static TransactionDefinition withDefaults() { return StaticTransactionDefinition.INSTANCE; } }
程式設計式使用Spring事務
有了上述這些API,就已經可以通過程式設計的方式實現Spring的事務控制了。
但是Spring官方建議不要直接使用PlatformTransactionManager
這一偏低層的API來程式設計,而是使用TransactionTemplate
和TransactionCallback
這兩個偏向使用者層的介面。
示例程式碼如下:
//設定事務的各種屬性;可以猜測TransactionTemplate應該是實現了TransactionDefinition transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); transactionTemplate.setTimeout(30000); //執行事務 將業務邏輯封裝在TransactionCallback中 transactionTemplate.execute(new TransactionCallback<Object>() { @Override public Object doInTransaction(TransactionStatus transactionStatus) { //.... 業務程式碼 } });
以上就是Spring事務最基本的原理。但是為什麼這些過程對我們似乎都不可見呢?那是因為這些過程都通過AOP的方式被織入了我們的業務邏輯中。
所以,像要深入瞭解Spring事務原理,還需要了解AOP的原理。
二、事務原理
AOP增強邏輯TransactionInterceptor,實現了MethodInterceptor由Spring AOP 原理可知內部就是增強邏輯
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {