日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring中事务内部调用引发的惨案

發(fā)布時間:2025/3/21 javascript 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring中事务内部调用引发的惨案 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在一個類內(nèi)部有2個方法foo和bar,其中bar方法配有注解(@Transactional),即bar是事務執(zhí)行的,而foo不是事務執(zhí)行,當foo方法內(nèi)部調(diào)用bar方法后,bar方法的事務是不生效的。示例代碼如下:

public?class?ServiceTest?{public?void?foo(){this.bar();//調(diào)用自身的方法;}@Transactionalpublic?void?bar(){System.out.println("this?is?bar");//數(shù)據(jù)庫操作} }

原因如下:

????Spring中通過注解來完成事務的功能,實際是通過SpringAOP來實現(xiàn)的,而SpringAOP中,使用this來調(diào)用自身的方法時,此對象引用上的方法直接會被調(diào)用,不會調(diào)用代理的方法(SpringAOP原理是產(chǎn)生代理類)。因此bar方法的事務不會生效。如果直接調(diào)用bar方法,此時事務是生效的。

????解決方法有:

????一、將bar方法放在另一個service類中。這種方法簡單,但是造成代碼的冗余。

????二、可以將注解@Transactional放在foo方法上。這種方法造成的影響:加入foo方法的一些操作是不需要事務的,這會延長事務執(zhí)行的時間。

????三、在foo方法中不要直接使用this來調(diào)用bar方法,通過調(diào)用代理類的bar方法。

public?void?foo(){if(null?!=?AopContext.currentProxy()){??((ServiceTest)AopContext.currentProxy()).bar();??}else{??bar();??}??????}

????我們顯示的調(diào)用了AopContext來獲取當前代理對象,然后調(diào)用其方法,這樣做還必須的一個步驟是將當前的代理暴露給線程使用,在配置文件中需要配置一個參數(shù):

<property?name="exposeProxy">??<value>true</value>??</property>

?

或者在application-context.xml文件中添加配置:

<aop:aspectj-autoproxy?proxy-target-class="true"?expose-proxy="true"/>

?

它是ProxyConfig的一個參數(shù),默認是false,如果不設置這個參數(shù),那么上述java代碼將無法獲取當前線程中的代理對象。

這種方法可以成功觸發(fā)攔截,但是也帶來了其他問題,比如代碼的織入,我們的代碼將變得復雜而且晦澀,而且嚴格要求系統(tǒng)針對于當前的bean必須配置攔截器,否則會因為找不到攔截器而拋出異常。

from:?https://my.oschina.net/hnrpf/blog/659673?

總結(jié)

以上是生活随笔為你收集整理的Spring中事务内部调用引发的惨案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。