Spring數據庫事務

  @Transactional 的所有可選屬性如下:

 

屬性 類型 默認值 說明
propagation Propagation枚舉 REQUIRED 事務傳播屬性 (下有說明)
isolation isolation枚舉 DEFAULT 事務隔離級別 (另有說明)
readOnly boolean false 是否只讀
timeout int -1 超時(秒)
rollbackFor Class[] {} 需要回滾的異常類
rollbackForClassName String[] {} 需要回滾的異常類名
noRollbackFor Class[] {} 不需要回滾的異常類
noRollbackForClassName String[] {} 不需要回滾的異常類名

 

  事務的傳播屬性 ,有如下可選

  可以去看spring源碼 : org.springframework.transaction.annotation.Propagation

 

REQUIRED 業務方法需要在一個事務中運行,如果方法運行時,已處在一個事務中,那麼就加入該事務,否則自己創建一個新的事務.這是spring默認的傳播行爲.
SUPPORTS 如果業務方法在某個事務範圍內被調用,則方法成爲該事務的一部分,如果業務方法在事務範圍外被調用,則方法在沒有事務的環境下執行.
MANDATORY 只能在一個已存在事務中執行,業務方法不能發起自己的事務,如果業務方法在沒有事務的環境下調用,就拋異常
REQUIRES_NEW 業務方法總是會爲自己發起一個新的事務,如果方法已運行在一個事務中,則原有事務被掛起,新的事務被創建,直到方法結束,新事務才結束,原先的事務纔會恢復執行.
NOT_SUPPORTED 聲明方法需要事務,如果方法沒有關聯到一個事務,容器不會爲它開啓事務.如果方法在一個事務中被調用,該事務會被掛起,在方法調用結束後,原先的事務便會恢復執行.
NEVER 聲明方法絕對不能在事務範圍內執行,如果方法在某個事務範圍內執行,容器就拋異常.只有沒關聯到事務,才正常執行.
NESTED 如果一個活動的事務存在,則運行在一個嵌套的事務中.如果沒有活動的事務,則按REQUIRED屬性執行.它使用了一個單獨的事務, 這個事務擁有多個可以回滾的保證點.內部事務回滾不會對外部事務造成影響, 它只對DataSourceTransactionManager 事務管理器起效.

 

  隔離級別:

  數據庫提供了四種事務隔離級別, 不同的隔離級別採用不同的鎖類開來實現.

  在四種隔離級別中, Serializable的級別最高, Read Uncommited級別最低.

  大多數數據庫的默認隔離級別爲: Read Commited,如Sql Server , Oracle.

  少數數據庫默認的隔離級別爲Repeatable Read, 如MySQL InnoDB存儲引擎

  即使是最低的級別,也不會出現 第一類 丟失 更新問題 .

  Read Uncommited :讀未提交數據( 會出現髒讀,不可重複讀,幻讀 ,避免了 第一類丟失 更新 )

  Read Commited :讀已提交的數據(會出現不可重複讀,幻讀)

  Repeatable Read :可重複讀(會出現幻讀)

  Serializable :串行化

  丟失 更新   :

  當兩個或多個事務選擇同一行,然後基於最初選定的值更新該行時,會發生丟失更新問題。每個事務都不知道其它事務的存在。最後的更新將重寫由其它事務所做的更新,這將導致數據丟失。

  例:

  事務A和事務B同時修改某行的值,

  1.事務A將數值改爲1並提交

  2.事務B將數值改爲2並提交。

  這時數據的值爲2,事務A所做的更新將會丟失。

  解決辦法:對行加鎖,只允許併發一個更新事務。

  髒讀: 一個事務讀到另一個事務未提交的更新數據

  例:

  1.Mary的原工資爲1000, 財務人員將Mary的工資改爲了8000(但未提交事務)

  2.Mary讀取自己的工資 ,發現自己的工資變爲了8000,歡天喜地!

  3.而財務發現操作有誤,回滾了事務,Mary的工資又變爲了1000, 像這樣,Mary記取的工資數8000是一個髒數據。

  不可重複讀: 在同一個事務中,多次讀取同一數據,返回的結果有所不同. 換句話說就是,後續讀取可以讀到另一個事務已提交的更新數據. 相反"可重複讀"在同一事務多次讀取數據時,能夠保證所讀數據一樣,也就是後續讀取不能讀到另一事務已提交的更新數據.

  例:

  1.在事務1中,Mary 讀取了自己的工資爲1000,操作並沒有完成

  2.在事務2中,這時財務人員修改了Mary的工資爲2000,並提交了事務.

  3.在事務1中,Mary 再次讀取自己的工資時,工資變爲了2000

  解決辦法:如果只有在修改事務完全提交之後纔可以讀取數據,則可以避免該問題。

  幻讀: 一個事務讀取到另一個事務已提交的insert數據.

  例:

  第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時 (此時第一事務還未提交) ,第二個事務向表中插入一行新數據。這時第一個事務再去讀取表時,發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。

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