spring 事務管理

一、什麼是事務

    咱們在開發時,會對數據進行持久化操做,如存入數據庫中。當咱們操做數據庫中的數據,後續可能會發生錯誤,拋出異常,前面對數據庫的操做就會不可靠,在這種狀況下須要回滾。spring

    事務的做用就是保證在事務中每一步操做都是可靠的,每一步操做均可以成功執行,中途出現錯誤或異常都要還原到事務開始前的狀態。數據庫

二、數據事務四種隔離機制和七種傳播行爲

2.1四種隔離機制

數據庫事務的隔離級別有4個,由低到高依次爲Read uncommitted、Read committed、Repeatable read、Serializable,這四個級別能夠逐個解決髒讀、不可重複讀、幻讀這幾類問題。數組

  •  ISOLATION_READ_UNCOMMITTED(讀取未提交內容):在該隔離級別,全部事務均可以看到其餘未提交事務的執行結果。本隔離級別不多用於實際應用,由於它的性能也不比其餘級別好多少。讀取未提交的數據,也被稱之爲髒讀(Dirty Read)。
  • ISOLATION_READ_COMMITTED(讀取提交內容):這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。它知足了隔離的簡單定義:一個事務只能看見已經提交事務所作的改變。這種隔離級別 也支持所謂的不可重複讀(Nonrepeatable Read),由於同一事務的其餘實例在該實例處理其間可能會有新的commit,因此同一select可能返回不一樣結果。
  • ISOLATION_REPEATABLE_READ(可重讀):這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在併發讀取數據時,會看到一樣的數據行。不過理論上,這會致使另外一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當用戶讀取某一範圍的數據行時,另外一個事務又在該範圍內插入了新行,當用戶再讀取該範圍的數據行時,會發現有新的「幻影」 行。InnoDB和Falcon存儲引擎經過多版本併發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。
  • ISOLATION_SERIALIZABLE(可串行化) : 這是最高的隔離級別,它經過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每一個讀的數據行上加上共享鎖。在這個級別,可能致使大量的超時現象和鎖競爭。

名詞解釋:併發

  • 髒讀(Drity Read):某個事務已更新一份數據,另外一個事務在此時讀取了同一份數據,因爲某些緣由,前一個RollBack了操做,則後一個事務所讀取的數據就會是不正確的。性能

  • 不可重複讀(Non-repeatable read):在一個事務的兩次查詢之中數據不一致,這多是兩次查詢過程當中間插入了一個事務更新的原有的數據。this

  •  幻讀(Phantom Read):在一個事務的兩次查詢中數據筆數不一致,例若有一個事務查詢了幾列(Row)數據,而另外一個事務卻在此時插入了新的幾列數據,先前的事務在接下來的查詢中,就會發現有幾列數據是它先前所沒有的。

spring 中的實現:spa

public enum Isolation {
    // 底層數據庫默認的隔離等級
    DEFAULT(-1),
    // 一個事務能夠讀取另外一個事務修改但尚未提交的數據。
    READ_UNCOMMITTED(1),
    // 該隔離級別表示一個事務只能讀取另外一個事務已經提交的數據。
    READ_COMMITTED(2),
    // 該隔離級別表示一個事務在整個過程當中能夠屢次重複執行某個查詢,而且每次返回的記錄都相同。即便在屢次查詢之間有新增的數據知足該查詢,這些新增的記錄也會被忽略。
    REPEATABLE_READ(4),
    // 全部的事務依次逐個執行,這樣事務之間就徹底不可能產生干擾,也就是說,該級別能夠防止髒讀、不可重複讀以及幻讀。
    SERIALIZABLE(8);

    private final int value;

    private Isolation(int value) {
        this.value = value;
    }

    public int value() {
        return this.value;
    }
}


2.2 七種傳播行爲

        2.2.1    PROPAGATION_REQUIRED:若是當前沒有事務,就建立一個新事務,若是當前存在事務,就加入該事務,該設置是最經常使用的設置。代理

        2.2.2    PROPAGATION_SUPPORTS:支持當前事務,若是當前存在事務,就加入該事務,若是當前不存在事務,就以非事務執行。code

        2.2.3     PROPAGATION_MANDATORY:支持當前事務,若是當前存在事務,就加入該事務,若是當前不存在事務,就拋出異常。對象

        2.2.4    PROPAGATION_REQUIRES_NEW:建立新事務,不管當前存不存在事務,都建立新事務。

        2.2.5    PROPAGATION_NOT_SUPPORTED:以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。

        2.2.6    PROPAGATION_NEVER:以非事務方式執行,若是當前存在事務,則拋出異常。

        2.2.7    PROPAGATION_NESTED:若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則執行與PROPAGATION_REQUIRED相似的操做。

    spring的實現:

public enum Propagation {

    // 若是當前存在事務,則加入該事務;若是當前沒有事務,則建立一個新的事務。
    // @Transactional 註解默認採用這個方案
    REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

    // 若是當前存在事務,則加入該事務;若是當前沒有事務,則以非事務的方式繼續運行。
    SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

    // 若是當前存在事務,則加入該事務;若是當前沒有事務,則拋出異常。
    MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

     // 建立一個新的事務,若是當前存在事務,則把當前事務掛起。
    REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

    // 以非事務方式運行,若是當前存在事務,則把當前事務掛起。
    NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

    // 以非事務方式運行,若是當前存在事務,則拋出異常。
    NEVER(TransactionDefinition.PROPAGATION_NEVER),

    // 若是當前存在事務,則建立一個事務做爲當前事務的嵌套事務來運行;若是當前沒有事務,則該取值等價於REQUIRED
    // 並不是全部的TransactionManager都能支持這個傳播級別
    NESTED(TransactionDefinition.PROPAGATION_NESTED);

    private final int value;

    Propagation(int value) { this.value = value; }

    public int value() { return this.value; }

}

三、@Transactional註解中經常使用參數說明

@Transactional註解中經常使用參數說明

參數名稱

功能描述

readOnly

該屬性用於設置當前事務是否爲只讀事務,設置爲true表示只讀,false則表示可讀寫,默認值爲false。例如:@Transactional(readOnly=true)

rollbackFor

該屬性用於設置須要進行回滾的異常類數組,當方法中拋出指定異常數組中的異常時,則進行事務回滾。例如:

指定單一異常類:@Transactional(rollbackFor=RuntimeException.class)

指定多個異常類:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

rollbackForClassName

該屬性用於設置須要進行回滾的異常類名稱數組,當方法中拋出指定異常名稱數組中的異常時,則進行事務回滾。例如:

指定單一異常類名稱:@Transactional(rollbackForClassName="RuntimeException")

指定多個異常類名稱:@Transactional(rollbackForClassName={"RuntimeException","Exception"})

noRollbackFor

該屬性用於設置不須要進行回滾的異常類數組,當方法中拋出指定異常數組中的異常時,不進行事務回滾。例如:

指定單一異常類:@Transactional(noRollbackFor=RuntimeException.class)

指定多個異常類:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})

noRollbackForClassName

該屬性用於設置不須要進行回滾的異常類名稱數組,當方法中拋出指定異常名稱數組中的異常時,不進行事務回滾。例如:

指定單一異常類名稱:@Transactional(noRollbackForClassName="RuntimeException")

指定多個異常類名稱:

@Transactional(noRollbackForClassName={"RuntimeException","Exception"})

propagation

該屬性用於設置事務的傳播行爲,具體取值可參考表6-7。

例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)

isolation

該屬性用於設置底層數據庫的事務隔離級別,事務隔離級別用於處理多事務併發的狀況,一般使用數據庫的默認隔離級別便可,基本不須要進行設置

timeout

該屬性用於設置事務的超時秒數,默認值爲-1表示永不超時

 

注意的幾點:

  • Propagation.REQUIRED內嵌套Propagation.REQUIRES_NEW時,它們註釋的方法必需要在不一樣的類中,不然Propagation.REQUIRES_NEW不會生效。
  • @Transactional 只能被應用到public方法上, 對於其它非public的方法,若是標記了@Transactional也不會報錯,但方法沒有事務功能.
  • 用 spring 事務管理器,由spring來負責數據庫的打開,提交,回滾.默認遇到運行期例外(throw new RuntimeException("註釋");)會回滾,即遇到不受檢查(unchecked)的例外時回滾;而遇到須要捕獲的例外(throw new Exception("註釋");)不會回滾,即遇到受檢查的例外(就是非運行時拋出的異常,編譯器會檢查到的異常叫受檢查例外或說受檢查異常)時,需咱們指定方式來讓事務回滾要想全部異常都回滾,要加上 @Transactional( rollbackFor={Exception.class,其它異常}) .若是讓unchecked例外不回滾: @Transactional(notRollbackFor=RunTimeException.class)
    以下:
@Transactional(rollbackFor=Exception.class) //指定回滾,遇到異常Exception時回滾
public void methodName() {
   throw new Exception("註釋");
}
@Transactional(noRollbackFor=Exception.class)//指定不回滾,遇到運行期例外(throw new RuntimeException("註釋");)會回滾
public ItimDaoImpl getItemDaoImpl() {
   throw new RuntimeException("註釋");
}
  • @Transactional 註解應該只被應用到 public 可見度的方法上。 若是你在 protected、private 或者 package-visible 的方法上使用 @Transactional 註解,它也不會報錯, 可是這個被註解的方法將不會展現已配置的事務設置。
  • @Transactional 註解能夠被應用於接口定義和接口方法、類定義和類的 public 方法上。然而,請注意僅僅 @Transactional 註解的出現不足於開啓事務行爲,它僅僅 是一種元數據,可以被能夠識別 @Transactional 註解和上述的配置適當的具備事務行爲的beans所使用。上面的例子中,其實正是 元素的出現 開啓 了事務行爲。
  • Spring團隊的建議是你在具體的類(或類的方法)上使用 @Transactional 註解,而不要使用在類所要實現的任何接口上。你固然能夠在接口上使用 @Transactional 註解,可是這將只能當你設置了基於接口的代理時它才生效。由於註解是不能繼承的,這就意味着若是你正在使用基於類的代理時,那麼事務的設置將不能被基於類的代理所識別,並且對象也將不會被事務代理所包裝(將被確認爲嚴重的)。所以,請接受Spring團隊的建議而且在具體的類上使用 @Transactional 註解。
相關文章
相關標籤/搜索