網頁

2020/11/4

Spring @Transactional 方法間呼叫的回滾範圍 methods call rollback boundaries

Spring @Transactional交易管理(事務管理)的幾種設定回滾範圍。

掛有@Transactional的方法代表一個資料庫交易,也就是應滿足ACID特性,一般非併發程序主要關注於交易失敗時的回滾範圍。而不同類別或同類別間的方法呼叫時,@Transactional會因掛載的方法的位置而有不同效果。以下整理了幾種常見的情況。

注意本篇只討論@Transactional預設的行為,使用預設的Spring AOP Proxy,且不討論屬性propagationrollbackFornoRollbackFor等其他設定。


下面的方法皆為public


設定一

@Transactional
+--------------+     +--------------+
|AClass.method1| --> |BClass.method1|
+--------------+     +--------------+

AClass.method1@Transactional有效果。
AClass.method1BClass.method1中發生錯誤則AClass.method1BClass.method1的交易都會回滾。


設定二

@Transactional       @Transactional
+--------------+     +--------------+
|AClass.method1| --> |BClass.method1|
+--------------+     +--------------+

AClass.method1@Transactional有效果。
BClass.method1@Transactional無效果,因為已經有AClass.method1的交易存在。
AClass.method1BClass.method1中發生錯誤則AClass.method1BClass.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.method1BClass.method1的交易會回滾。但BClass.method1發生錯誤時有捕捉例外,所以BClass.method1發生錯誤時不會觸發AClass.method1的回滾。


設定五

@Transactional
try-catch
+--------------+     +--------------+
|AClass.method1| --> |BClass.method1|
+--------------+     +--------------+

AClass.method1@Transactional無效果。AClass.method1BClass.method1中發生錯誤有捕捉錯誤則AClass.method1BClass.method1的交易不會回滾。(之前寫成會回滾,在此修正


設定六

@Transactional
+--------------+     +--------------+
|AClass.method1| --> |AClass.method2|
+--------------+     +--------------+

AClass.method1@Transactional有效果。
AClass.method1AClass.method2中發生錯誤則AClass.method1AClass.method2的交易都會回滾。效果同設定一。


設定七

@Transactional       @Transactional
+--------------+     +--------------+
|AClass.method1| --> |AClass.method2|
+--------------+     +--------------+

AClass.method1@Transactional有效果。
AClass.method2@Transactional無效果,因為同類別中被呼叫方法的@Transactional無作用。
AClass.method1AClass.method2中發生錯誤則AClass.method1AClass.method2的交易都會回滾。效果同設定六。


設定八

                     @Transactional
+--------------+     +--------------+
|AClass.method1| --> |AClass.method2|
+--------------+     +--------------+

AClass.method2@Transactional無效果,因為同類別中被呼叫方法的@Transactional無作用。
AClass.method1AClass.method2中發生錯誤則AClass.method1AClass.method2的交易都不會回滾。


以上是一些工作上常碰到的情況,如果再配合@Transactional其他屬性設定會有更多種排列組合。如果問題再擴展到併發程式、分散式架構及非同步交易等會有更多要處理的問題。

若本篇有幫助到您還幫忙點個Google廣告,感恩。


沒有留言:

張貼留言