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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【每日提高之声明式事物】spring声明式事务 同一类内方法调用事务失效

發布時間:2025/6/17 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【每日提高之声明式事物】spring声明式事务 同一类内方法调用事务失效 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

【問題】

?????? Spring的聲明式事務,我想就不用多介紹了吧,一句話“自從用了Spring AOP啊,事務管理真輕松啊,真輕松;事務管理代碼沒有了,腦不酸了,手不痛了,一口氣全配上了事務;輕量級,測試起來也簡單,嘿!”。不管從哪個角度看,輕量級聲明式事務都是一件解放生產力的大好事。所以,我們“一直用它”。

????? 不過,最近的一個項目里,卻碰到了一個事務管理上的問題:有一個服務類,其一個聲明了事務的方法,里面做了三次插入SQL操作,但是在后面出錯回滾時,卻發現前面插入成功了,也是說,這個聲明了事務的方法,實際上并沒有真正啟動事務!怎么回事呢?難道Spring的聲明式事務失效了?

?

【分析】

? ? ?這個問題,表面上是事務聲明失效的問題,實質上很可能是Spring的AOP機制實現角度的問題。我想到很久以前研究Spring的AOP實現時發現的一個現象:對于以Cglib方式增強的AOP目標類,會創建兩個對象,一個事Bean實例本身,一個是Cglib增強代理對象,而不僅僅是只有后者。

? ? ?我們知道,Spring的AOP實現方式有兩種:1、Java代理方式;2、Cglib動態增強方式,這兩種方式在Spring中是可以無縫自由切換的。Java代理方式的優點是不依賴第三方jar包,缺點是不能代理類,只能代理接口。

Spring通過AopProxy接口,抽象了這兩種實現,實現了一致的AOP方式:

現在看來,這種抽象同樣帶了一個缺陷,那就是抹殺了Cglib能夠直接創建普通類的增強子類的能力,Spring相當于把Cglib動態生成的子類,當普通的代理類了,這也是為什么會創建兩個對象的原因。下圖顯示了Spring的AOP代理類的實際調用過程:

因此,從上面的分析可以看出,methodB沒有被AopProxy通知到,導致最終結果是:被Spring的AOP增強的類,在同一個類的內部方法調用時,其被調用方法上的增強通知將不起作用。

????

????? 而這種結果,會造成什么影響呢:

????? 1:內部調用時,被調用方法的事務聲明將不起作用

????? 2:換句話說,你在某個方法上聲明它需要事務的時候,如果這個類還有其他開發者,你將不能保證這個方法真的會在事務環境中

????? 3:再換句話說,Spring的事務傳播策略在內部方法調用時將不起作用。不管你希望某個方法需要單獨事務,是RequiresNew,還是要嵌套事務,要Nested,等等,統統不起作用。

????? 4:不僅僅是事務通知,所有你自己利用Spring實現的AOP通知,都會受到同樣限制。。。。

【解難】

?????

????? 問題的原因已經找到,其實,我理想中的AOP實現,應該是下面這樣:

使用代理

1、Proxy.insertAAA() 代理對象加了事物,這樣就可以增強事物。

public?void?a()?{??aopProxy.b();//即調用AOP代理對象的b方法即可執行事務切面進行事務增強??}??

判斷一個Bean是否是AOP代理對象可以使用如下三種方法:

AopUtils.isAopProxy(bean)????????:?是否是代理對象;

AopUtils.isCglibProxy(bean)???????:?是否是CGLIB方式的代理對象;

AopUtils.isJdkDynamicProxy(bean)?:?是否是JDK動態代理方式的代理對象;

  • <aop:aspectj-autoproxy?expose-proxy="true"/><!—注解風格支持-->??
  • <aop:config?expose-proxy="true"><!—xml風格支持-->? ?
  • 修改我們的代碼

    this.b();-----------修改為--------->((AService) AopContext.currentProxy()).b();

    ?

    在使用的過程中,提示錯誤:

    關于AOP無法切入同類調用方法的問題,給方式使用注解

    @Transactional(propagation = Propagation.REQUIRED,
    ?? ?isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)

    文章參考:

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

    https://blog.csdn.net/aya19880214/article/details/50640596

    轉載于:https://my.oschina.net/maojindaoGG/blog/1920783

    總結

    以上是生活随笔為你收集整理的【每日提高之声明式事物】spring声明式事务 同一类内方法调用事务失效的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。