1. 程式人生 > >Spring事務內方法呼叫自身事務 增強的三種方式

Spring事務內方法呼叫自身事務 增強的三種方式

ServiceA.java檔案:

 

 

檢視Spring Tx的相關日誌:  可以看到只建立了一個事物ServiceA.service方法的事務,但是callSelf方法卻沒有被事務增強;

         分析原因:Spring事務生成的物件也是被Cglib或JDK代理的物件,就區別於該物件本身了,

代理的物件執行方法之前會走攔截器鏈,就不能同this方法.

 

         解決方案:

  1. 使用Autowired註解將自身注入,然後呼叫注入屬性的方法;

 

驗證輸出結果:  確實初始化了callSelf的事務;

 

 

2.之前Aop可以將代理物件暴露到當前執行緒區域性變數中;

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

 

通過嘗試發現,SpringTx也可以使用該配置,將建立的物件加入到當前執行緒區域性變數;

也許覺得SpringAop和SpringTx不一樣啊,但其實兩者都實現了AbstractAutoProxyCreator類,同樣設定expose-proxy也能生效,繫結到執行緒區域性變數上;

呼叫方式如下:

 

         驗證輸出結果:可以看到確實 callSelf方法也被Spring事務增強到了.

 

 

3.按照道理來說tx:annotation-driven標籤應該也有expose-proxy屬性,但是很不幸:

<tx:annotation-driven>標籤確實不允許expose-proxy屬性設定,有proxy-target-class屬性;

檢視AopNamespaceUtils的useClassProxyingIfNecessary方法:

Line  91-94行是用來解析標籤時候定義expose-proxy、proxy-target-class兩個屬性,Aop以及Tx都會呼叫這個方法, 問題就是這裡了, <aop:aspectj-autoproxy>標籤約束裡有expose-proxy,

那可以解析,但是<tx:annotation-driven>標籤沒有expose-proxy我解析啥子呢,

改動下解析Tx標籤時,將expose-proxy設定為true; (此處涉及到改動原始碼,jar包是無法直接修改的,我修改的Spring的原始碼,如果需要匯入Spring的jar包 然後在修改之後匯出成jar包)

 

驗證下輸出結果: 可以看到也實現了呼叫自身方法, 其實和方法二應該是一個意思;

   附上筆記地址:

  https://files.cnblogs.com/files/lvbinbin2yujie/Spring%E4%BA%8B%E5%8A%A1%E6%96%B9%E6%B3%95%E8%B0%83%E7%94%A8%E8%87%AA%E8%BA%AB.rar