圖解Spring事務管理及Mysql事務隔離級別傳播行爲

1、事務的特性

  • Atomicity原子性:事務做爲一個總體被執行,包含在其中的對數據庫的操做要麼所有被執行,要麼都不執行。
  • Consistency一致性:事務應確保數據庫的狀態從一個一致狀態轉變爲另外一個一致狀態。一致狀態的含義是數據庫中的數據應知足完整性約束。
  • Isolation隔離性:多個事務併發執行時,一個事務的執行不該影響其餘事務的執行。
  • Durability持久性:已被提交的事務對數據庫的修改應該永久保存在數據庫中。

2、Spring事務管理方式

  • 1.編程式

Spring事務管理-編程式

優勢:控制靈活,直觀易理解。數據庫

缺點:將事務代碼放入業務邏輯中,破壞了代碼的條理性。編程

  • 2.聲明式(AOP、註解)

Spring事務管理-聲明式.jpg
 

優勢:簡單,不影響業務代碼(Spring推薦)。segmentfault

缺點:控制粒度只到方法級別併發

3、Spring事務屬性

  • 四種隔離級別

<property name="isolationLevelName" value="ISOLATION_READ_COMMITTED"/>優化

  • 七種事務傳播行爲

<property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/>spa

  • 事務超時

事務超時屬性定義一個事務容許執行的最長時間,達到最長時間沒有完成事務,則回滾,單位秒。
<property name="timeout" value="30"/>  code

  • 事務的只讀屬性。

提示數據庫驅動程序和數據庫系統,這個事務並不包含寫入操做,數據庫就有可能該事務進行一些特定的優化,好比不安排相應的數據庫鎖,以減輕事務對數據庫的壓力。orm

<property name=「readOnly" value=「true"/>blog

  • 事務的回滾屬性

默認事務中拋出未檢查異常(繼承Error或RuntimeException的異常)則回滾,沒有異常或已檢查異常則提交。默認是這樣的,能夠經過設置回滾屬性修改。繼承

<property name =「rollbackFor" value =「xxxException"/>   
<property name =「noRollbackFor " value =「xxxException "/>
  • 聲明式事務配置

傳播行爲 [,隔離級別] [,只讀屬性] [,超時屬性] [不影響提交的異常] [,致使回滾的異常]

<property name="*Service"> PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,TIMEOUT_20, +AbcException,+DefException,-HijException </property>  

4、事務隔離級別

隔離級別是指若干個併發的事務之間的隔離程度。 併發事務之間的讀寫控制策略。

會出現哪些併發一致性問題

  • 丟失修改:一個事務對數據進行了修改,在事務提交以前,另外一個事務對同一個數據進行了修改,覆蓋了以前的修改;
  • 髒讀(Dirty Read):一個事務讀取了被另外一個事務修改、但未提交(進行了回滾)的數據,形成兩個事務獲得的數據不一致;
  • 不可重複讀(Nonrepeatable Read):在同一個事務中,某查詢操做在一個時間讀取某一行數據和以後一個時間讀取該行數據,發現數據已經發生修改(可能被更新或刪除了);
  • 幻讀(Phantom Read):當同一查詢屢次執行時,因爲其它事務在這個數據範圍內執行了插入操做,會致使每次返回不一樣的結果集(和不可重複讀的區別:針對的是一個數據總體/範圍;而且須要是插入操做)

四種隔離級別

事務隔離級別.jpg
 
MySQL的「一致性讀」機制,能夠保證在REPEATABLE_READ級別下解決「幻讀」問題。(基於InnoDB的multi-versioning )

5、事務傳播行爲

  • 所謂事務的傳播行爲是指,若是在開始當前事務以前,一個事務上下文已經存在,此時有若干選項能夠指定一個事務性方法的執行行爲。
  • 當事務存在嵌套關係時,子事務與父事務的關係以及回滾的影響範圍(傳播-回滾的傳播)
  • 示例定義:
T1{
 
  O(A);
 
  T2{
    O(B);
 
    O(C); 
  };
 
  O(D); 
};

6、各類傳播性的關係

1.PROPAGATION_REQUIRED=0:
若是當前存在事務,則加入該事務;若是當前沒有事務,則建立一個新的事務。
  • 無父事務時:子事務做爲獨立事務執行
  • 有父事務時:子事務中的操做串入父事務中執行,而且一塊兒提交,一個操做失敗所有回滾
2.PROPAGATION_SUPPORTS=1:
若是當前存在事務,則加入該事務;若是當前沒有事務,則以非事務的方式繼續運行。
  • 無父事務時:以非事務方式執行
  • 有父事務時:加入父事務執行,等同於PROPAGATION_REQUIRED
3.PROPAGATION_MANDATORY=2:
若是當前存在事務,則加入該事務;若是當前沒有事務,則拋出異常。
  • 無父事務時:拋出異常
  • 有父事務時:加入父事務執行,等同於PROPAGATION_REQUIRED
4.PROPAGATION_REQUIRES_NEW=3:
建立一個新的事務,若是當前存在事務,則把當前事務掛起。
掛起(Suspend):通知 TransactionManager再也不檢查某事務的狀態,直到Resume

AbstractPlatformTransactionManager. handleExistingTransaction()

  • 無父事務時:子事務新建事務做爲獨立事務執行
  • 有父事務時:子事務新建事務做爲獨立事務執行,獨立提交;
T1{
 
  O(A);
 
  T2{
    O(B);
 
    O(C); 
  };
 
  O(D); 
};

如此示例:

  • 子事務T2不受父事務T1回滾的影響,但仍做爲T1的子邏輯,
  • O(D)失敗,O(A)回滾,T2中的事務不回滾;
  • T2失敗回滾,T1捕獲異常後,能夠選擇提交或回滾,未捕獲異常,同T2一塊兒回滾。
5.NOT_SUPPORTED=4:
以非事務方式運行,若是當前存在事務,則把當前事務掛起。
  • 無父事務時:以非事務方式執行
  • 有父事務時:掛起父事務,本身按照無事務方式運行
  子事務自身無回滾,出現異常若向上拋,可能致使父事務回滾
  父事務回滾時,不會影響子事務。
6.NEVER=5:
以非事務方式運行,若是當前存在事務,則拋出異常。
  • 無父事務時:以非事務方式執行
  • 有父事務時:拋出異常(若不處理會致使父事務回滾)
7.NESTED=6:
若是當前存在事務,則建立一個事務做爲當前事務的嵌套事務來運行
  • 無父事務時:建立獨立事務,等同於PROPAGATION_REQUIRED
  • 有父事務時:嵌套在父事務以內
子事務依賴父事務:子事務於父事務提交時提交;父事務回滾,子事務也回滾。
Savepoint:子事務回滾時,父事務不回滾
一張圖總結各事務傳播屬性的關係

事務傳播屬性之間的關係.jpg


版權聲明:本文爲博主「開花樹Tree」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://segmentfault.com/a/11...

相關文章
相關標籤/搜索