欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解決方法A調(diào)用方法B的事務(wù)控制問題

 更新時間:2023年07月26日 09:13:54   作者:繪碼先生  
這篇文章主要介紹了解決方法A調(diào)用方法B的事務(wù)控制問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

關(guān)于方法A調(diào)用方法B的事務(wù)控制問題

在這里插入圖片描述

實測,不管是上圖還是下圖,得到的結(jié)論都是一致的,那就是:

前提是同一個類里的方法調(diào)用,controller層類調(diào)用service的B方法,事務(wù)自然會生效的

a.異常發(fā)生后,被調(diào)用方法(B)是否添加事務(wù)控制,對于事務(wù)的回滾是否并不產(chǎn)生影響

b.調(diào)用B的方法,添加了事務(wù)控制才能實現(xiàn)異常事務(wù)回滾,不管被調(diào)用方法B是否有事務(wù)控制

c.不管嵌套調(diào)用了多少個方法,只要最頂層方法(沒被同一個類中其他方法調(diào)用的且調(diào)用了同一個類里其他方法的方法),有事務(wù)控制,那么不管是哪個被調(diào)用的方法異常,整個調(diào)用的業(yè)務(wù)數(shù)據(jù)都回滾,不管被調(diào)用的方法是否有添加了事務(wù)的控制

在這里插入圖片描述

其實,最好的辦法是根據(jù)自己實際調(diào)用的情況,模擬測試一下就知道了。

同一個類的不同方法,A方法沒有@Transactional,B方法有@Transactional,A調(diào)用B方法,事務(wù)不起作用

問題

同一個類的不同方法,A方法沒有@Transactional,B方法有@Transactional,A調(diào)用B方法,事務(wù)不起作用

原理解析

spring 在掃描bean的時候會掃描方法上是否包含@Transactional注解,如果包含,spring會為這個bean動態(tài)地生成一個子類(即代理類,proxy),代理類是繼承原來那個bean的。

此時,當(dāng)這個有注解的方法被調(diào)用的時候,實際上是由代理類來調(diào)用的,代理類在調(diào)用之前就會啟動transaction。

然而,如果這個有注解的方法是被同一個類中的其他方法調(diào)用的,那么該方法的調(diào)用并沒有通過代理類,而是直接通過原來的那個bean,所以就不會啟動transaction,我們看到的現(xiàn)象就是@Transactional注解無效。

? ? //接口
? ? interface Service {
? ? ? ? void A();
? ? ? ? void B();
? ? }
? ? //目標(biāo)類,實現(xiàn)接口
? ? class ServiceImpl implements Service {
? ? ? ? //no annotation here
? ? ? ? @Override
? ? ? ? public void A() {
? ? ? ? ? ? this.B();
? ? ? ? }
?? ??? ?@Transactional
? ? ? ? @Override
? ? ? ? public void B() {
? ? ? ? ? ? System.out.println("execute doNeedTx in ServiceImpl");
? ? ? ? }
? ? }
? ? //代理類,也要實現(xiàn)相同的接口
? ? class ProxyByJdkDynamic implements Service {
? ? ? ? //包含目標(biāo)對象
? ? ? ? private Service target;
? ? ? ? public ProxyByJdkDynamic(Service target) {
? ? ? ? ? ? this.target = target;
? ? ? ? }
? ? ? ? //目標(biāo)類中此方法帶注解,進(jìn)行特殊處理
? ? ? ? @Override
? ? ? ? public void B() {
? ? ? ? ? ? //開啟事務(wù)
? ? ? ? ? ? System.out.println("-> create Tx here in Proxy");
? ? ? ? ? ? //調(diào)用目標(biāo)對象的方法,該方法已在事務(wù)中了
? ? ? ? ? ? target.B();
? ? ? ? ? ? //提交事務(wù)
? ? ? ? ? ? System.out.println("<- commit Tx here in Proxy");
? ? ? ? }
? ? ? ? //目標(biāo)類中此方法沒有注解,只做簡單的調(diào)用
? ? ? ? @Override
? ? ? ? public void A() {
? ? ? ? ? ? //直接調(diào)用目標(biāo)對象方法
? ? ? ? ? ? target.A();
? ? ? ? }
? ? }

那回到一開始的問題,我們調(diào)用的方法A不帶注解,因此代理類不開事務(wù),而是直接調(diào)用目標(biāo)對象的方法。

當(dāng)進(jìn)入目標(biāo)對象的方法后,執(zhí)行的上下文已經(jīng)變成目標(biāo)對象本身了,因為目標(biāo)對象的代碼是我們自己寫的,和事務(wù)沒有半毛錢關(guān)系,此時你再調(diào)用帶注解的方法,照樣沒有事務(wù),只是一個普通的方法調(diào)用而已。

簡單來說,內(nèi)部調(diào)用本類方法,不會再走代理了,所以B的事務(wù)不起作用

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論