spring事務屬性的幾個試驗

首先咱們知道,spring的事務管理有如下幾種事務屬性:
PROPAGATION_REQUIRED--支持當前事務,若是當前沒有事務,就新建一個事務。這是最多見的選擇。
 PROPAGATION_SUPPORTS--支持當前事務,若是當前沒有事務,就以非事務方式執行。
 PROPAGATION_MANDATORY--支持當前事務,若是當前沒有事務,就拋出異常。
 PROPAGATION_REQUIRES_NEW--新建事務,若是當前存在事務,把當前事務掛起。
 PROPAGATION_NOT_SUPPORTED--以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
 PROPAGATION_NEVER--以非事務方式執行,若是當前存在事務,則拋出異常。
 PROPAGATION_NESTED--若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則進行與PROPAGATION_REQUIRED 相似的操做。


=======================
針對這些事務屬性,我作了幾回試驗。
使用的代碼簡單描述就是:
外層方法{

try{內層方法();}catchRuntimeException e{}
}

內層方法(){
拋出 RuntimeException 
}

=======================
REQUIRED的試驗時,配置是:
<tx:method name="外層方法" propagation="REQUIRED" />
<tx:method name="內層方法" propagation="REQUIRED" />
在日誌中看到:
1、爲外層方法建立事務
- Creating new transaction with name [外層方 法]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2、爲內層方法配置事務
 - Participating in existing transaction
能夠看到 ,內層方法使用的是外層方法的事務上下文。而後,當內層方法拋出異常時,日誌中記錄:
Setting JDBC transaction [...] rollback-only
即要求該事務回滾。可是內層方法的異常被外層方法捕獲並處理了, 外層方法仍然會繼續執行,並在執行完畢後提交事務。這時日誌中記錄並拋出異常:
Global transaction is marked as rollback-only but transactional code requested commit
(執行事務回滾...
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

 
所謂 支持當前事務 就是在當前事務的上下文內執行目標方法。 內層方法對事務的操做會影響到外層方法。
=========================
NESTED 的試驗時,配置以下:
<tx:method name="外層方法" propagation="REQUIRED" />
<tx:method name="內層方法" propagation="NESTED" />
在日誌中看到:
1、爲外層方法建立事務
- Creating new transaction with name [外層方 法]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2、爲內層方法建立嵌套事務
-  Creating nested transaction with name [ 內層方法 ]
一、 內層方法回滾、提交
 - Rolling back transaction to savepoint
二、 外層方法繼續執行並提交
外層方法邏輯輸出
- Triggering beforeCommit synchronization
……
 
可見,嵌套事務與當前事務能夠認爲是兩個事務,只是它不會掛起當前事務。嵌套事務即便回滾,當前事務仍然能夠正常提交。
=======================
SUPPORTS試驗時, 使用的配置是:
<tx:method name="外層方法" propagation="SUPPORTS" />
<tx:method name="內層方法" propagation=" REQUIRED " />
另外內層方法改成了:
內層方法(){
return
}
這種方案下,日誌中只有爲內層方法建立事務的記錄,對外層方法基本是「漠不關心」的。而若是把配置反過來,改爲
<tx:method name="外層方法" propagation=" REQUIRED " />
<tx:method name="內層方法" propagation="SUPPORTS" />
那麼, spring會爲外層方法建立事務,而對內存方法則使用外層方法的事務上下文。
可是,若是配置爲:
<tx:method name="外層方法" propagation="SUPPORTS" />
<tx:method name="內層方法" propagation="SUPPORTS" />
日誌中會出現幾行這樣的記錄:
Triggering beforeCommit synchronization
Triggering beforeCompletion synchronization
Triggering afterCommit synchronization
Triggering afterCompletion synchronization
這些是事務提交先後的日誌;可是卻找不到建立事務相關的日誌。我不清楚爲何會出現這種事務先後行爲不匹配的狀況。之後再琢磨琢磨吧。
======================
其它的幾種狀況我沒有再測試了。不過,事務相關配置的基本含義到這裏差很少已經清楚了,其它的狀況能夠「同理可證」或者「由此推知」了吧。
相關文章
相關標籤/搜索