Spring事務隔離級別和傳播性

Spring事務配置屬性:html

屬性 類型 默認值 說明
propagation Propagation REQUIRED 事務傳播屬性
isolation isolation DEFAULT 事務隔離級別
readOnly boolean false 只讀事務
timeout int -1 超時(秒)

readOnly 
事務屬性中的readOnly標誌表示對應的事務應該被最優化爲只讀事務。若是值爲true就會告訴Spring我這個方法裏面沒有insert或者update,你只須要提供只讀的數據庫Connection就好了,這種執行效率會比read-write的Connection高,因此這是一個最優化提示。在一些狀況下,一些事務策略可以起到顯著的最優化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)時避免dirty checking(試圖「刷新」)。 
數據庫

timeout 
在屬性中還有定義「timeout」值的選項,指定事務超時爲幾秒。通常不會使用這個屬性。在JTA中,這將被簡單地傳遞到J2EE服務器的事務協調程序,並據此獲得相應的解釋。 
服務器

Isolation Level(事務隔離等級):併發

爲何事務要有Isolation Level這個屬性?先回顧下數據庫事務的知識: 
第一類丟失更新(lost update):在徹底未隔離事務的狀況下,兩個事務更新同一條數據資源,某一事務異常終止,回滾形成第一個完成的更新也同時丟失。 
第二類丟失更新(second lost updates):是不可重複讀的特殊狀況,若是兩個事務都讀取同一行,而後兩個都進行寫操做,並提交,第一個事務所作的改變就會丟失。 
髒讀(dirty read):若是第二個事務查詢到第一個事務還未提交的更新數據,造成髒讀。由於第一個事務你還不知道是否提交,因此數據不必定是正確的。 
虛讀(phantom read):一個事務執行兩次查詢,第二次結果集包含第一次中沒有或者某些行已被刪除,形成兩次結果不一致,只是另外一個事務在這兩次查詢中間插入或者刪除了數據形成的。 
不可重複讀(unrepeated read):一個事務兩次讀取同一行數據,結果獲得不一樣狀態結果,如中間正好另外一個事務更新了該數據,兩次結果相異,不可信任。 
工具

DEFAULT:採用數據庫默認隔離級別 
SERIALIZABLE:最嚴格的級別,事務串行執行,資源消耗最大; 
REPEATABLE_READ:保證了一個事務不會修改已經由另外一個事務讀取但未提交(回滾)的數據。避免了「髒讀取」和「不可重複讀取」的狀況,可是帶來了更多的性能損失。 
READ_COMMITTED:大多數主流數據庫的默認事務等級,保證了一個事務不會讀到另外一個並行事務已修改但未提交的數據,避免了「髒讀取」。該級別適用於大多數系統。 
READ_UNCOMMITTED:保證了讀取過程當中不會讀取到非法數據。隔離級別在於處理多事務的併發問題。 
性能

註解形式@Transactional實現事務管理 
注意@Transactional只能被應用到public方法上,對於其它非public的方法,若是標記了@Transactional也不會報錯,但方法沒有事務功能。 
默認狀況下,一個有事務的方法,遇到RuntiomeException時會回滾。遇到受檢查的異常是不會回滾的,要想全部異常都回滾,要加上屬性rollbackFor={Exception.class}
優化

transaction-manager:指定事務管理器名字,默認爲transactionManager,當使用其餘名字時須要明確指定; spa

proxy-target-class:默認false表示使用JDK代理,若是爲true將使用CGLIB代理 代理

order:定義事務通知順序,默認Ordered.LOWEST_PRECEDENCE,表示將順序決定權交給AOP來處理。 
建議只在實現類或實現類的方法上使用@Transactional,而不要在接口上使用,這是由於若是使用JDK代理機制是沒問題,由於其使用基於接口的代理;而使用使用CGLIB代理機制時就會遇到問題,由於其使用基於類的代理而不是接口,這是由於接口上的@Transactional註解是「不能繼承的
」。 orm

所謂事務傳播行爲就是多個事務方法相互調用時,事務如何在這些方法間傳播。Spring 支持 7 種事務傳播行爲:

  • PROPAGATION_REQUIRED 若是當前沒有事務,就新建一個事務,若是已經存在一個事務中,加入到這個事務中。這是最多見的選擇。

  • PROPAGATION_SUPPORTS 支持當前事務,若是當前沒有事務,就以非事務方式執行。

  • PROPAGATION_MANDATORY 使用當前的事務,若是當前沒有事務,就拋出異常。

  • PROPAGATION_REQUIRES_NEW 新建事務,若是當前存在事務,把當前事務掛起。

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

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

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

    Spring 默認的事務傳播行爲是 PROPAGATION_REQUIRED,它適合於絕大多數的狀況。假設 ServiveX#methodX() 都工做在事務環境下(即都被 Spring 事務加強了),假設程序中存在以下的調用鏈:Service1#method1()->Service2#method2()->Service3#method3(),那麼這 3 個服務類的 3 個方法經過 Spring 的事務傳播機制都工做在同一個事務中。

詳細的事務傳播方面的理解能夠參考:http://www.docin.com/p-368876161.html

補充:

Spring事務的4個屬性,簡稱:ACID

A:原子性,C:一致性,I:隔離性,D:持久性

相關文章
相關標籤/搜索