1. 程式人生 > 其它 >SpringAOP[2]-@Transaction原理

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。但是最為基本的就是PlatformTransactionManagerTransactionDefintionTransactionStatus

事務管理器——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來程式設計,而是使用TransactionTemplateTransactionCallback這兩個偏向使用者層的介面。
示例程式碼如下:

//設定事務的各種屬性;可以猜測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 {