spring的事務傳播行爲及事務隔離級別

事務的特性(ACID):

1. 原子性(Atomicity):  事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。

2. 一致性(Consistency): 事務前後數據的完整性必須保持一致

3. 隔離性(Isolation):一個事務的執行不能被其他事務干擾,即一個事務內部的操作及使用的數據對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。

4. 持久性(Durability):一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來的其他操作和數據庫故障不應該對其有任何影響。



在一個典型的應用中,併發是不可避免的,多個事務併發運行,操作同一個數據來完成任務。併發可能會導致以下問題:
1、髒讀(Dirty read):一個事務讀取了被另一個事務改寫但還未提交的數據時。如果這些數據被回滾,那麼之前的事務讀取的到數據就是無效的。

2、不可重複讀(Nonrepeatable read):在同一事務中,多次讀取同一數據返回的結果有所不同(讀到另一個事務提交的更新的數據)。

3、幻讀(Phantom read):一個事務讀取幾行記錄後,另一個事務插入了一些記錄(也可以刪除),幻讀就發生了。在後來的查詢中第一個事務就會發現有些原來沒有的記錄。


事務隔離級別:

1、讀未提交(READ_UNCOMMITED):允許讀取還未提交的改變了的數據。可能導致髒讀、幻讀、不可重複讀。

2、讀已提交(READ_COMMITED):允許在併發事務已經提交後讀取。可防止髒讀,但幻讀、不可重複讀仍可能發生。

3、可重複讀(REPEATABLE_READ):對相同字段的多次讀取是一致的,除非數據被事務本身改變。可防止髒讀、不可重複讀。但幻讀仍可能發生。

4、可串行化(SERIALIZABLE):完全服從ACID的隔離級別,確保不發生髒讀、幻讀和不可重複讀。他在所有的隔離級別中是最慢的,畢竟要完全鎖住在事務中涉及的數據表。

5、Default:使用了後端數據庫默認的隔離級別(spring中的選擇項,也是isolation屬性的默認值,Mysql默認採用REPEATABLE_READ隔離級別,Oracle默認採用READ_COMMITED隔離級別)。


再來個表格看的清楚些:



事務傳播行爲:

事務的傳播行爲是爲了解決業務層方法之間相互調用,產生的事務應該如何進行傳遞的問題。spring有如下7種傳播行爲:

1、PROPAGATION_REQUIRED:支持當前事務,如果當前不存在事務則新建一個。

2、PROPAGATION_SUPPORTS:支持當前事務,如果不存在,就不使用事務。

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

4、PROPAGATION_REQUIRES_NEW:如果當前有事務存在,掛起當前事務,創建一個新的事務。

5、PROPAGATION_NOT_SUPPORTED:以非事務方式運行,如果當前有事務存在,掛起當前事務。

6、PROPAGATION_NEVER:以非事務方式運行,如果當前有事務存在,拋出異常。

7、PROPAGATION_NESTED:如果當前存在一個事務,則該方法運行在一個嵌套的事務中。被嵌套的事務可以從當前事務中單獨的提交和回滾。如果當前不存在事務,則開始一個新的事務。各廠商對這種傳播行爲的支持參差不齊,使用時需注意。 


可以看出1、2、3爲一組,都表現對當前事務的支持,不同的在於當前不存在事務的處理方式;4、5、6爲一組,都表現對當前事務的不支持,不同的在於當前有事務的處理方式。然後7單獨一組。


舉個小栗子,比如有一個service中有方法A,調用了方法B,方法B的傳播行爲是PROPAGATION_REQUIRED,那麼如果方法A的傳播行爲也是PROPAGATION_REQUIRED,方法A運行的時候,開啓了一個事務,方法A中執行到方法B的時候,察覺到當前已經有事務了,方法B就不會再創建新的事務,直接包含在方法A的事務當中。


隔離級別和傳播行爲在spring中的配置:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
     <tx:attributes>
          <tx:method name="query*" read-only="true" propagation="SUPPORTS" />
          <tx:method name="get*" read-only="true" propagation="SUPPORTS" />
          <tx:method name="insert*" propagation="REQUIRED" />
          <tx:method name="save*" propagation="REQUIRED" />
          <tx:method name="update*" propagation="REQUIRED" />
          <tx:method name="remove*" propagation="REQUIRED" />
          <tx:method name="delete*"  propagation="REQUIRED" />
     </tx:attributes>
</tx:advice>
由於沒有給method配置isolation屬性,所以默認是isolation=‘DEFAULT’,也就是使用後端數據庫默認的隔離級別。




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