Spring事務管理+SpringBoot中事務代碼實現

談談對Spring中事務管理的理解

結合在慕課網中的課程去談Spring的事務。

Spring的事務管理提供了三個重要接口,分別是PlatformTransactionManager,TransactionDefinition、TransactionStatus。

我們分別介紹一下,PlatformTransactionManager是Spring爲事務提供的平臺事務管理器,所有的Spring事務都依賴與該接口或該接口的實現類。其中幾個我們比較常用的實現類有DataSourceTransactionManager(Jdbc中的事務管理)、JtaTransactionManager(Jta事務管理)、WeblogicJtaTransactionManager(常見的Jpa事務管理)、HibernateTransactionManager(Hibernate事務管理)等,主要用來對事務進行管理,如事務提交、回滾等。

然後是TransactionDefinition(事務定義器)接口,該接口主要定義了事務的Propagation(傳播行爲),Isolation(隔離級別),Timeout(超時),以及readOnly(只讀)。說到這裏我們要談一下事務的傳播行爲和隔離級別的知識。

    1、傳播行爲,Spring事務管理中的傳播行爲有PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、    PROPAGATION_SUPPORT、PROPAGATION_MANDATORY、PROPAGATION_NOT_SUPPORT、PROPAGATION_NEVER、PROPAGATION_NESTED。

PROPAGATION_REQUIRED:支持當前事務,如果當前事務不存在則新建事務,這是Spring的默認選擇

PROPAGATION_REQUIRES_NEW:不支持當前事務,如果當前事務存在則掛起,並使用新事務執行,兩個事務之間沒有關係

PROPAGATION_SUPPORT:支持當前事務,如果當前事務不存在,則以非事務方式執行

PROPAGATION_MANDATORY:支持當前事務,如果當前事務不存在,則拋出異常

PROPAGATION_NOT_SUPPORT:不支持當前事務,如果當前存在事務,則將事務掛起,以非事務的方式執行

PROPAGATION_NEVER:不支持當前事務,如果當前存在事務,則拋出異常

PROPAGATION_NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中。如果沒有活動事務,則按REQUIRED屬性執行。它使用了一個單獨的事務,這個事務擁有多個可以回滾的保存點。內部事務的回滾不會對外部事務造成影響。它只對DataSourceTransactionManager事務管理器起效。

2、事務的隔離級別

Spring事務中有五種隔離級別,其中四種對應數據庫的四種隔離級別,另外一種是默認的隔離級別,根據數據庫類型自適應。

ISOLATION_DEFAULT:默認隔離級別,如果時Oracle數據庫,默認是ISOLATION_READ_COMMITED,如果時mysql,默認是ISOLATION_REPEATABLE_READ。

ISOLATION_READ_UNCOMMITED:讀-不提交,此方式可能會導致髒讀、不可重複讀和幻讀。

ISOLATION_READ_COMMITED:讀-提交,此方式可以防止髒讀,但可能導致不可重複和幻讀。

ISOLATION_REPEATABLE_READ:可重複-讀,此方式可以防止髒讀和不可重複讀,但是可能出現幻讀

ISOLATION_SERIALIZABLE:串行,此方式以串行方式執行,代價高,但是能防止髒讀、不可重複讀、幻讀。

至於什麼是髒讀、不可重複讀和幻讀:

髒讀:是指當前事務讀取的數據是另一個事務未提交的內容,當另一個事務回滾後,則當前事務讀取的數據爲髒數據。

不可重複讀:指的是同一事務中多次讀取的數據不一致,當前事務讀取的數據被另外一個事務修改了,當前事務進行對數據進行處理時,發現數據和數據庫中數據不一致。

幻讀:指的是當前事務連續幾次進行同樣的操作,獲得的數據條數不一致。側重的是新增和刪除。

TransactionDefinition接口中還提供了一個獲取當前事務傳播行爲和隔離級別的方法:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.transaction;

import org.springframework.lang.Nullable;

public interface TransactionDefinition {
    .....
    //獲取傳播行爲
    int getPropagationBehavior();
    //獲取隔離級別
    int getIsolationLevel();
    //獲取設置的超時時間
    int getTimeout();
    //獲取是否只讀
    boolean isReadOnly();

    @Nullable
    String getName();
}

最後是TransactionStatus接口,該接口提供一些獲取當前事務狀態的方法

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.transaction;

import java.io.Flushable;

public interface TransactionStatus extends SavepointManager, Flushable {
    //是否是新建事務
    boolean isNewTransaction();
    //是否擁有保存點
    boolean hasSavepoint();
    //設置事務需要回滾
    void setRollbackOnly();
    //是否需要回滾
    boolean isRollbackOnly();
    //用於刷新底層會話中的修改到數據庫,一般用於刷新如Hibernate/JPA的會話,可能對如JDBC類型的事 
      務無任何影響;
    void flush();
    //當前事務是否完成
    boolean isCompleted();
}

 

Spring的事務管理相關知識已經瞭解的差不多了,Spring的事務分類方式有很多種,在實現層面把Spring事務分爲編程式和聲明式。

下面的項目中對Spring事務使用一種編程式和三種聲明式的方式實現,並通過了單元測試。具體實現有需要的同學可以研究代碼去吧,這裏就不詳細講解了。

具體實現代碼:https://github.com/tiedungao/transaction

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