spring 事務處理中,同一個類中:A方法(無事務)調B方法(有事務),事務不生效問題



    
    
   
   
           
  1. public class MyEntry implements IBaseService{
  2. public String A(String jsonStr) throws Exception{
  3. UserInfo user = null;
  4. UserDetail userDetail = null;
  5. this.getUserMsg(user,userDetail ,jsonStr);
  6. if( null!= user){
  7. this.B(user,userDetail);
  8. }
  9. return "";
  10. }
  11. //此處需要事務
  12. private String B(UserInfo user, UserDetail detail) throws DBException{
  13. baseDao.saveObject(user);
  14. baseDao.saveObject(detail);
  15. }
  16. }

<tx:method name="A" propagation="REQUIRED" />

那么如果baseDao.saveObject(detail)異常,整個B方法全部回滾。沒問題

但是

如果我在配置事務的時候僅僅對 name="B",並且不對A進行配置事務,如下:

<tx:method name="B" propagation="REQUIRED" />


那么如果baseDao.saveObject(detail)異常,方法B不能全部回滾(也就是說雖然baseDao.saveObject(detail)沒有保存成功,但是baseDao.saveObject(user)保存成功了)

在 spring 中一共定義了六種事務傳播屬性,如下

PROPAGATION_REQUIRED -- 支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。
PROPAGATION_SUPPORTS -- 支持當前事務,如果當前沒有事務,就以非事務方式執行。
PROPAGATION_MANDATORY -- 支持當前事務,如果當前沒有事務,就拋出異常。
PROPAGATION_REQUIRES_NEW -- 新建事務,如果當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED -- 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER -- 以非事務方式執行,如果當前存在事務,則拋出異常。
PROPAGATION_NESTED -- 如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。
前六個策略類似於EJB CMT,第七個(PROPAGATION_NESTED)是Spring所提供的一個特殊變量。

它要求事務管理器或者使用JDBC 3.0 Savepoint API提供嵌套事務行為(如Spring的DataSourceTransactionManager)

研究源碼、調試程序得出結論:
A如果沒有受事務管理:  則線程內的connection 的 autoCommit為true。
B得到事務時事務傳播特性依然生效,得到的還是A使用的connection,但是 不會改變autoCommit的屬性。
所以B當中是按照每條sql進行提交的。

在一個Service內部,事務方法之間的嵌套調用,普通方法和事務方法之間的嵌套調用,都不會開啟新的事務.是因為spring采用動態代理機制來實現事務控制,而動態代理最終都是要調用原始對象的,而原始對象在去調用方法時,是不會再觸發代理了!

解決辦法:

可以把方法B放到另外一個service或者dao,然后把這個server或者dao通過@Autowired注入到方法A的bean里面,這樣即使方法A沒用事務,方法B也可以執行自己的事務了。

參考文章:

https://www.jianshu.com/p/0da29e4f354a

http://blog.csdn.net/dapinxiaohuo/article/details/52092447

http://www.iteye.com/topic/35907/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM