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

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

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

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

在這里插入圖片描述

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

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

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

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

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

在這里插入圖片描述

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

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

問(wèn)題

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

原理解析

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

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

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

? ? //接口
? ? interface Service {
? ? ? ? void A();
? ? ? ? void B();
? ? }
? ? //目標(biāo)類,實(shí)現(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");
? ? ? ? }
? ? }
? ? //代理類,也要實(shí)現(xiàn)相同的接口
? ? class ProxyByJdkDynamic implements Service {
? ? ? ? //包含目標(biāo)對(duì)象
? ? ? ? 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)對(duì)象的方法,該方法已在事務(wù)中了
? ? ? ? ? ? target.B();
? ? ? ? ? ? //提交事務(wù)
? ? ? ? ? ? System.out.println("<- commit Tx here in Proxy");
? ? ? ? }
? ? ? ? //目標(biāo)類中此方法沒(méi)有注解,只做簡(jiǎn)單的調(diào)用
? ? ? ? @Override
? ? ? ? public void A() {
? ? ? ? ? ? //直接調(diào)用目標(biāo)對(duì)象方法
? ? ? ? ? ? target.A();
? ? ? ? }
? ? }

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

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

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

總結(jié)

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

相關(guān)文章

最新評(píng)論