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

spring @Transactional 無效的解決方案

 更新時間:2019年03月26日 14:22:54   作者:dezun  
這篇文章主要介紹了spring @Transactional 無效的解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

關(guān)于@Transactional注解 一般都認(rèn)為要注意以下三點

1 .在需要事務(wù)管理的地方加@Transactional 注解。@Transactional 注解可以被應(yīng)用于接口定義和接口方法、類定義和類的 public 方法上 。

2 . @Transactional 注解只能應(yīng)用到 public 可見度的方法上 。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不會報錯, 但是這個被注解的方法將不會展示已配置的事務(wù)設(shè)置。

3 . 注意僅僅 @Transactional 注解的出現(xiàn)不足于開啟事務(wù)行為,它僅僅 是一種元數(shù)據(jù)。必須在配置文件中使用配置元素,才真正開啟了事務(wù)行為。

最近在項目中發(fā)現(xiàn)注解無效,經(jīng)過跟蹤源代碼發(fā)現(xiàn)了問題,于是在網(wǎng)上找到相同出現(xiàn)此問題的人,以下為原文,講解的很詳細(xì):

只要避開Spring目前的AOP實現(xiàn)上的限制,要么都聲明要事務(wù),要么分開成兩個類,要么直接在方法里使用編程式事務(wù)

[問題]

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

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

[探幽]

其實以前也會碰到有人說,Spring的事務(wù)配置不起作用,但是根據(jù)第一反應(yīng)和以往經(jīng)驗,我總會告訴他,肯定是你的配置有問題啦;所以這一次,我想也不會例外,大概是把事務(wù)注解配在了接口上而不是實現(xiàn)方法上,或者,如果是用XML聲明方式的話,很可能是切入點的表達(dá)式?jīng)]有配對。

 不過,在檢查了他們的配置后,卻發(fā)現(xiàn)沒有配置問題,該起事務(wù)的實現(xiàn)方法上,用了@Transactional事務(wù)注解聲明,XML里也配了注解驅(qū)動<tx:annotation-driven .../>,配置很正確啊,怎么會不起作用?

我很納悶,于是往下問:

問1:其他方法有這種情況么?

答1:沒有。

問2:這個方法有什么特別的么(以下簡稱方法B)?

答2:就是調(diào)后臺插了三條記錄啊,沒啥特別的。

問3:這個方法是從Web層直接調(diào)用的吧?

答3:不是,是這個Service類(以下簡稱ServiceA)的另外一個方法調(diào)過來的(以下簡稱方法A)。

問4:哦,那個調(diào)用它的方法配了事務(wù)么(問題可能在這了)?

 答4:沒有。

問5:那WEB層的Action(用的是Struts2),調(diào)用的是沒有聲明事務(wù)的方法A,方法A再調(diào)用聲明了事務(wù)的方法B?

答5:對的。

問6:你直接在方法A上加上事務(wù)聲明看看

答6:好。。。

看來可能找到問題所在了,于是把@Transactional也加在方法A上,啟動項目測試,結(jié)果是:事務(wù)正常生效,方法A和方法B都在一個事務(wù)里了。

好了,現(xiàn)在總結(jié)一下現(xiàn)象:

1、ServiceA類為Web層的Action服務(wù)

2、Action調(diào)用了ServiceA的方法A,而方法A沒有聲明事務(wù)(原因是方法A本身比較耗時而又不需要事務(wù))

3、ServiceA的方法A調(diào)用了自己所在class的方法B,而方法B聲明了事務(wù),但是方法B的事務(wù)聲明在這種情況失效了。

4、如果在方法A上也聲明事務(wù),則在Action調(diào)用方法A時,事務(wù)生效,而方法B則自動參與了這個事務(wù)。

我讓他先把A也加上事務(wù)聲明,決定回來自己再測一下。

這個問題,表面上是事務(wù)聲明失效的問題,實質(zhì)上很可能是Spring的AOP機(jī)制實現(xiàn)角度的問題。

我想到很久以前研究Spring的AOP實現(xiàn)時發(fā)現(xiàn)的一個現(xiàn)象:對于以Cglib方式增強(qiáng)的AOP目標(biāo)類,會創(chuàng)建兩個對象,一個事Bean實例本身,一個是Cglib增強(qiáng)代理對象,而不僅僅是只有后者。我曾經(jīng)疑惑過這一點,但當(dāng)時沒有再仔細(xì)探究下去。

 我們知道,Spring的AOP實現(xiàn)方式有兩種:1、Java代理方式;2、Cglib動態(tài)增強(qiáng)方式,這兩種方式在Spring中是可以無縫自由切換的。

Java代理方式的優(yōu)點是不依賴第三方j(luò)ar包,缺點是不能代理類,只能代理接口。

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

 

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

因此,從上面的分析可以看出,methodB沒有被AopProxy通知到, 導(dǎo)致最終結(jié)果是:

被Spring的AOP增強(qiáng)的類,在同一個類的內(nèi)部方法調(diào)用時,其被調(diào)用方法上的增強(qiáng)通知將不起作用。

而這種結(jié)果,會造成什么影響呢: 1:內(nèi)部調(diào)用時,被調(diào)用方法的事務(wù)聲明將不起作用 2:換句話說,你在某個方法上聲明它需要事務(wù)的時候,如果這個類還有其他開發(fā)者,你將不能保證這個方法真的會在事務(wù)環(huán)境中 3:再換句話說,Spring的事務(wù)傳播策略在內(nèi)部方法調(diào)用時將不起作用。

不管你希望某個方法需要單獨事務(wù),是RequiresNew,還是要嵌套事務(wù),要Nested,等等,統(tǒng)統(tǒng)不起作用。
4:不僅僅是事務(wù)通知,所有你自己利用Spring實現(xiàn)的AOP通知,都會受到同樣限制。。。。

[解難]

問題的原因已經(jīng)找到,其實,我理想中的AOP實現(xiàn),應(yīng)該是下面這樣:

只要一個Cglib增強(qiáng)對象就好,對于Java代理方式,我的選擇是毫不猶豫的拋棄。

至于前面的事務(wù)問題,只要避開Spring目前的AOP實現(xiàn)上的限制,要么都聲明要事務(wù),要么分開成兩個類,要么直接在方法里使用編程式事務(wù),那么一切OK。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • System.currentTimeMillis()計算方式與時間的單位轉(zhuǎn)換詳解

    System.currentTimeMillis()計算方式與時間的單位轉(zhuǎn)換詳解

    這篇文章主要介紹了System.currentTimeMillis()計算方式與時間的單位轉(zhuǎn)換詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 手把手教你使用Java實現(xiàn)在線生成pdf文檔

    手把手教你使用Java實現(xiàn)在線生成pdf文檔

    在實際的業(yè)務(wù)開發(fā)的時候,常常會需要把相關(guān)的數(shù)據(jù)信息,通過一些技術(shù)手段生成對應(yīng)的PDF文件,然后返回給用戶。本文將手把手教大家如何利用Java實現(xiàn)在線生成pdf文檔,需要的可以參考一下
    2022-03-03
  • Mybatis批量新增的三種實現(xiàn)方式

    Mybatis批量新增的三種實現(xiàn)方式

    文章講述了在Java中進(jìn)行批量操作的最佳實踐,包括使用MyBatis的ExecutorType.BATCH模式,作者建議根據(jù)實際需求選擇是否進(jìn)行批量操作,因為批量操作并不總是能提升性能,且有副作用,如無法獲取自增ID等
    2024-12-12
  • JNI實現(xiàn)最簡單的JAVA調(diào)用C/C++代碼

    JNI實現(xiàn)最簡單的JAVA調(diào)用C/C++代碼

    這篇文章主要介紹了JNI實現(xiàn)最簡單的JAVA調(diào)用C/C++代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • java中@requestMappling注解的使用

    java中@requestMappling注解的使用

    本文主要介紹了java中@requestMappling注解的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Java之NoClassDefFoundError的原因及分析

    Java之NoClassDefFoundError的原因及分析

    在Java開發(fā)中,經(jīng)常會遇到ClassNotFoundException和NoClassDefFoundError異常,ClassNotFoundException發(fā)生在編譯時JVM無法找到類,而NoClassDefFoundError則發(fā)生在運行時JVM無法加載類,這兩個異常雖然原因相似,但有本質(zhì)區(qū)別
    2024-09-09
  • 手把手教你設(shè)置IntelliJ IDEA 的彩色代碼主題的圖文教程

    手把手教你設(shè)置IntelliJ IDEA 的彩色代碼主題的圖文教程

    本文給出一系列 IntelliJ IDEA 代碼的彩色主題,感興趣的朋友一起看看吧
    2018-01-01
  • Spring?Boot?中?@Value注解的使用示例詳解

    Spring?Boot?中?@Value注解的使用示例詳解

    @Value是Spring提供的一個注解,用于從配置文件或其他來源(如系統(tǒng)環(huán)境變量、SpEL表達(dá)式)中讀取值并注入到Bean的字段或方法參數(shù)中,這篇文章主要介紹了SpringBoot中@Value注解的使用,需要的朋友可以參考下
    2025-05-05
  • spring boot打包成可執(zhí)行jar包

    spring boot打包成可執(zhí)行jar包

    本篇文章主要介紹了spring boot打包成可執(zhí)行jar包,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • Java基礎(chǔ)之常用的命令行指令

    Java基礎(chǔ)之常用的命令行指令

    這篇文章主要介紹了Java基礎(chǔ)之常用的命令行指令,文中有非常詳細(xì)的圖文示例,對正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04

最新評論