分佈式事務【3】【Spring的事務抽象】

1 Spring的事務抽象

  • PlatformTransactionManager // 事務管理器
  • TransactionDefinition //事務的一些基礎信息,如超時時間、隔離級別、傳播屬性等
  • TransactionStatus //事務的一些狀態信息,如是否一個新的事務、是否已被標記爲回滾

1.1 PlatformTransactionManager

public interface PlatformTransactionManager extends TransactionManager {
    //根據事務定義TransactionDefinition獲取事務
    TransactionStatus getTransaction(TransactionDefinition var1);
    //提交事務
    void commit(TransactionStatus var1);
    //回滾事務
    void rollback(TransactionStatus var1);
}

1.2 TransactionDefinition  

事務的隔離級別是數據庫本身的事務功能,事務的傳播屬性則是Spring爲我們提供的功能

public interface TransactionDefinition {
    //---------------隔離機制---------------------------------------------------
    // 默認隔離機制(和數據庫保持一致)
    ISOLATION_DEFAULT
    // 讀未提交
    ISOLATION_READ_UNCOMMITTED
    // 讀已提交
    ISOLATION_READ_COMMITTED
    // 可重複讀
    ISOLATION_REPEATABLE_READ
    // 線性讀
    ISOLATION_SERIALIZABLE
    //---------------傳播機制---------------------------------------------------
    // 支持當前事務;如果A方法已經在事務中,則B事務將直接使用;否則將創建新事務(默認)
    PROPAGATION_REQUIRED
    // 支持當前事務;如果A方法已經在事務中,則B事務將直接使用;否則將以非事務狀態執行
    PROPAGATION_SUPPORTS
    // 支持當前事務;如果A方法沒有事務,則拋出異常
    PROPAGATION_MANDATORY
    // 將創建新的事務,如果A方法已經在事務中,則將A事務掛起
    PROPAGATION_REQUIRES_NEW
    // 不支持當前事務,總是以非事務狀態執行;如果A方法已經在事務中,則將其掛起
    PROPAGATION_NOT_SUPPORTED
    // 不支持當前事務,如果A方法在事務中,則拋出異常
    PROPAGATION_NEVER
    // 嵌套事務,底層將使用Savepoint形成嵌套事務
    PROPAGATION_NESTED
    //-------------------------------------------------------------------------
    // 獲取事務的傳播屬性
    int getPropagationBehavior();
    // 獲取事務的隔離級別
    int getIsolationLevel();
    // 獲取事務的名字
    String getName();
    // 獲取事務的超時時間
    int getTimeout();
    // 事務是否是隻讀
    boolean isReadOnly();
}

TransactionDefinition的實現DefaultTransactionDefinition,默認的事務定義

//org.springframework.transaction.support
public class DefaultTransactionDefinition implements TransactionDefinition{
    //事務的傳播屬性爲PROPAGATION_REQUIRED,即當前沒有事務的時候創建一個,如果有則使用當前事務 
    private int propagationBehavior = PROPAGATION_REQUIRED;
    //事務的隔離級別採用底層數據庫默認的隔離級別 
    private int isolationLevel = ISOLATION_DEFAULT;
    //超時時間採用底層數據庫默認的超時時間
    private int timeout = TIMEOUT_DEFAULT;
    //是否只讀爲false
    private boolean readOnly = false;
    //...
}

事務傳播機制

當事務方法被另一個事務方法調用時,必須指定事務應該如何傳播。例如:方法可能繼續在現有事務中運行,也可能開啓一個新事務,並在自己的事務中運行。

事務傳播機制(https://blog.csdn.net/qq_40794973/article/details/97522518 | https://www.jianshu.com/p/c8140591a2a1  )

傳播屬性

描述

REQUIRED

如果有事務在運行,當前的方法就在這個事務內運行;否則就啓動一個新的事務,並在自己的事務內運行(默認)

REQUIRES_NEW 當前的方法必須啓動新事務,並在它自己的事務內運行;如果有事務正在運行,應該將它掛起
SUPPORTS 如果有事務在運行,當前的方法就在這個事務內運行;否則它可以不運行在事務中
NOT_SUPPORTED 當前的方法不應該運行在事務中;如果有運行的事務,將它掛起
MANDATORY 當前的方法必須運行在事務內部;如果沒有正在運行的事務,就拋出異常
NEVER 當前的方法不應該運行在事務中;如果有運行的事務,就拋出異常
NESTED  如果有事務在運行,當前的方法就應該在這個事務的嵌套事務內運行;否則就啓動一個新的事務,並在它自己的事務內運行

1.3 TransactionStatus

//事務在運行中的狀態
//TransactionStatus它繼承了SavepointManager接口,SavepointManager是對事務中上述保存點功能的封裝
//TransactionStatus本身更多存儲的是事務的一些狀態信息
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
    // 是否是新的事務
    boolean isNewTransaction();
    // 是否有恢復點
    boolean hasSavepoint();
    // 設置爲只回滾
    void setRollbackOnly();
    // 是否爲只回滾
    boolean isRollbackOnly();
    // 是否已完成
    boolean isCompleted();
}

2 在Spring中使用事務

2.1 使用代碼方式實現

2.2 Transactional標籤方式實現

//javax.transaction.Transactional ×
//org.springframework.transaction.annotation.Transactional √
public @interface Transactional {
	// 當在配置文件中有多個TransactionManager , 可以用該屬性指定選擇哪個事務管理器
	@AliasFor("transactionManager")
	String value() default "";
	@AliasFor("value")
	String transactionManager() default "";
	// 事務的傳播行爲
	Propagation propagation() default Propagation.REQUIRED;
	// 事務的隔離級別
	Isolation isolation() default Isolation.DEFAULT;
	// 事務的超時時間
	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
	// 指定事務是否爲只讀事務,默認值爲false(爲了忽略那些不需要事務的方法,比如讀取數據,可以設置 read-only 爲 true)
	boolean readOnly() default false;
	// 用於指定能夠或不能夠觸發事務回滾的異常類型(多個逗號分隔)
	Class<? extends Throwable>[] rollbackFor() default {};
	String[] rollbackForClassName() default {};
	Class<? extends Throwable>[] noRollbackFor() default {};
	String[] noRollbackForClassName() default {};
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章