事務復原的判斷
基于注解中的配置資訊,可以得出逾時或者抛出指定異常的情況下,會執行事務的復原。
但是預設逾時時間是-1,即不設逾時時間
指定抛出異常的話預設是對RuntimeException和Error的子類
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
Class<? extends Throwable>[] rollbackFor() default {};
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
1.REQUIRED
REQUIRED是@Transactional 預設的傳播等級,即如果目前存在事務則不再建立新事物。如果目前不存在事務則建立事務。
舉例:ServiceA 調用 ServiceB
情況 1. A開啟了事務且傳播等級為REUQIRED,那麼B則不會建立事務,如果抛出異常的話AB一起復原
2. A如果沒有開啟事務,B開啟事務則是B異常復原,A不受影響
2. REQUIRED_NEW
會建立事務,目前如果存在事務則挂起目前事務重新建立事務。
舉例:ServiceA 調用 ServiceB(A為REUQIRED級别,B為REQUIRED_NEW級别)
情況 1. A調用B,如果B已經送出了,說明B的事務已經執行完成了。這時候A抛出異常,那麼隻會将A的事務復原。
2. A調用B,B抛出異常且事務復原了,這時候如果異常被A捕獲到,那麼具體看對捕獲的異常的處理來判斷是否復原。但是如果沒有捕獲到的話那麼A肯定復原。
3. SUPPROT
支援目前事務,如果無事務則按非事務方式運作
舉例:ServiceA 調用 ServiceB
情況 1. ServiceB配置事務傳播等級為SUPPORT , 那麼B是否按事務方式運作全看A是否有事務。如果A存在事務,則AB在一個事務内,有異常全部復原。
4. NOT_SUPPROT
不支援目前事務,如果有事務則将目前事務挂起,以非事務的狀态運作
舉例:ServiceA 調用 ServiceB(A -> REQUIRED , B -> NOT_SUPPORT )
情況 1. 無論A是否存在事務,B都是會按非事務狀态去執行
5. NEVER
不支援事務,如果目前存在事務,則抛出異常
舉例:ServiceA 調用 ServiceB(A為REUQIRED級别,B為NEVER 級别)
情況 1. A 調用 B , B直接抛出異常。
6. MANDATORY
支援目前事務,如果目前沒有事務則抛出異常
舉例:ServiceA 調用 ServiceB
情況 1. 如果A未配置事務,B配置傳播等級為MANDATORY則直接抛出異常,如果A配置事務,則正常執行AB在同一事務内。
7. NESTED
如果目前存在事務,則會建立一個嵌套的子事務,且在嵌套的子事務内執行。如果不存在事務,那麼和REQUIRED差不多
舉例:ServiceA 調用 ServiceB
失敗復原狀态:
1. B已經送出成功 如果A失敗復原 B進行復原操作
2. B失敗復原 如果抛出的異常在A中被try catch捕獲處理 則A看處理結果判斷是否進行失敗復原 ,若沒有沒A捕獲處理 則A肯定復原
使用NESTED的重點
1.設定 transactionManager 的 nestedTransactionAllowe 為 true, 預設值是false。
2. JDBC driver 必須支援 JDBC 3.0
3. JDK 版本必須 1.4 +