【每日提升之聲明式事物】spring聲明式事務 同一類內方法調用事務失效

【問題】html

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

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

 

【分析】測試

     這個問題,表面上是事務聲明失效的問題,實質上極可能是Spring的AOP機制實現角度的問題。我想到好久之前研究Spring的AOP實現時發現的一個現象:對於以Cglib方式加強的AOP目標類,會建立兩個對象,一個事Bean實例自己,一個是Cglib加強代理對象,而不只僅是隻有後者。ui

     咱們知道,Spring的AOP實現方式有兩種:一、Java代理方式;二、Cglib動態加強方式,這兩種方式在Spring中是能夠無縫自由切換的。Java代理方式的優勢是不依賴第三方jar包,缺點是不能代理類,只能代理接口。this

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

如今看來,這種抽象一樣帶了一個缺陷,那就是抹殺了Cglib可以直接建立普通類的加強子類的能力,Spring至關於把Cglib動態生成的子類,當普通的代理類了,這也是爲何會建立兩個對象的緣由。下圖顯示了Spring的AOP代理類的實際調用過程:.net

所以,從上面的分析能夠看出,methodB沒有被AopProxy通知到,致使最終結果是:被Spring的AOP加強的類,在同一個類的內部方法調用時,其被調用方法上的加強通知將不起做用。代理

    

      而這種結果,會形成什麼影響呢:code

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

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

      3:再換句話說,Spring的事務傳播策略在內部方法調用時將不起做用。無論你但願某個方法須要單獨事務,是RequiresNew,仍是要嵌套事務,要Nested,等等,通通不起做用。

      4:不只僅是事務通知,全部你本身利用Spring實現的AOP通知,都會受到一樣限制。。。。

【解難】

     

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

使用代理

一、Proxy.insertAAA() 代理對象加了事物,這樣就能夠加強事物。

public void a() {  

aopProxy.b();//即調用AOP代理對象的b方法便可執行事務切面進行事務加強  

}  

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

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

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

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

  1. <aop:aspectj-autoproxy expose-proxy="true"/><!—註解風格支持-->  
  2. <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

相關文章
相關標籤/搜索