Spring @Transactional
交易管理(事務管理)的幾種設定回滾範圍。
掛有@Transactional
的方法代表一個資料庫交易,也就是應滿足ACID特性,一般非併發程序主要關注於交易失敗時的回滾範圍。而不同類別或同類別間的方法呼叫時,@Transactional
會因掛載的方法的位置而有不同效果。以下整理了幾種常見的情況。
注意本篇只討論@Transactional
預設的行為,使用預設的Spring AOP Proxy,且不討論屬性propagation
、rollbackFor
、noRollbackFor
等其他設定。
下面的方法皆為public
。
設定一
@Transactional
+--------------+ +--------------+
|AClass.method1| --> |BClass.method1|
+--------------+ +--------------+
AClass.method1
的@Transactional
有效果。
AClass.method1
或BClass.method1
中發生錯誤則AClass.method1
到BClass.method1
的交易都會回滾。
設定二
@Transactional @Transactional
+--------------+ +--------------+
|AClass.method1| --> |BClass.method1|
+--------------+ +--------------+
AClass.method1
的@Transactional
有效果。
BClass.method1
的@Transactional
無效果,因為已經有AClass.method1
的交易存在。
AClass.method1
或BClass.method1
中發生錯誤則AClass.method1
到BClass.method1
的交易都會回滾。設定效果同設定一。
設定三
@Transactional
+--------------+ +--------------+
|AClass.method1| --> |BClass.method1|
+--------------+ +--------------+
AClass.method1
無交易管理。
BClass.method1
的@Transactional
有效果。
AClass.method1
中發生錯誤AClass.method1
的交易不會回滾。
BClass.method1
中發生錯誤則BClass.method1
的交易會回滾。
設定四
@Transactional try-catch
+--------------+ +--------------+
|AClass.method1| --> |BClass.method1|
+--------------+ +--------------+
AClass.method1
的@Transactional
有效果。
AClass.method1
中發生錯誤則AClass.method1
及BClass.method1
的交易會回滾。但BClass.method1
發生錯誤時有捕捉例外,所以BClass.method1
發生錯誤時不會觸發AClass.method1
的回滾。
設定五
@Transactional
try-catch
+--------------+ +--------------+
|AClass.method1| --> |BClass.method1|
+--------------+ +--------------+
AClass.method1
的@Transactional
無效果。AClass.method1
或BClass.method1
中發生錯誤有捕捉錯誤則AClass.method1
及BClass.method1
的交易不會回滾。(之前寫成會回滾,在此修正)
設定六
@Transactional
+--------------+ +--------------+
|AClass.method1| --> |AClass.method2|
+--------------+ +--------------+
AClass.method1
的@Transactional
有效果。
AClass.method1
或AClass.method2
中發生錯誤則AClass.method1
到AClass.method2
的交易都會回滾。效果同設定一。
設定七
@Transactional @Transactional
+--------------+ +--------------+
|AClass.method1| --> |AClass.method2|
+--------------+ +--------------+
AClass.method1
的@Transactional
有效果。
AClass.method2
的@Transactional
無效果,因為同類別中被呼叫方法的@Transactional
無作用。
AClass.method1
或AClass.method2
中發生錯誤則AClass.method1
到AClass.method2
的交易都會回滾。效果同設定六。
設定八
@Transactional
+--------------+ +--------------+
|AClass.method1| --> |AClass.method2|
+--------------+ +--------------+
AClass.method2
的@Transactional
無效果,因為同類別中被呼叫方法的@Transactional
無作用。
AClass.method1
或AClass.method2
中發生錯誤則AClass.method1
到AClass.method2
的交易都不會回滾。
以上是一些工作上常碰到的情況,如果再配合@Transactional
其他屬性設定會有更多種排列組合。如果問題再擴展到併發程式、分散式架構及非同步交易等會有更多要處理的問題。
若本篇有幫助到您還幫忙點個Google廣告,感恩。
沒有留言:
張貼留言