添加PROPAGATION_REQUIRES_NEW 事務沒有產生作用


一、描述
Spring遇到嵌套事務時,當被嵌套的事務被定義為“PROPAGATION_REQUIRES_NEW”時,
內層Service的方法被調用時,外層方法的事務被掛起;
內層事務相對於外層事務是完全獨立的,有獨立的隔離性等等。

二、實驗
但實驗時卻遇到一個奇怪的問題:
1、當ServiceA.a()方法調用ServiceB.b()方法時,內層事務提交和回滾,都不受外層事務提交或回滾的影響。
2、當ServiceA.a()方法調用ServiceA.c()方法時,內層事務不能正確地提交或回滾。

三、演示代碼
XXXService中,有下面兩個方法:
@Transactional 
method_One() {
    method_Two();
}


@Transactional(propagation = Propagation.REQUIRES_NEW) 
method_Two(){
    //do something
}

四、分析和結論
1、method_Two()會不會創建一個新事務? 
答:不會創建。仔細查看了日志,沒有找到類似creating new transaction的輸出,應該是因為在同一個Service類中,spring並不重新創建新事務,如果是兩不同的Service,就會創建新事務了。 
那么為什么spring只對跨Service的方法才生效? 
Debug代碼發現跨Service調用方法時,都會經過org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor.intercept()方法,只有經過此處,才能對事務進行控制。 

2、不同的Service調用方法時:
如果被調用方法是Propagation.REQUIRES_NEW,被catch后不拋出,事務可以正常提交; 
如果被調用方法是Propagation.REQUIRED,被catch后不拋出,后面的代碼雖然可以執行下去,但最終還是會分出rollback-only異常;

3、同一個Service中調用方法時:
不論注解是Propagation.REQUIRES_NEW 還是 Propagation.REQUIRED,
其結果都是一樣的,就是都被忽略掉了,等於沒寫。
當其拋出異常時,只需catch住不拋出,事務就可以正常提交。


免責聲明!

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



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