最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring事務(wù)@Transactional失效原因及解決辦法小結(jié)

 更新時間:2023年08月20日 10:47:23   作者:程序猿(攻城獅)  
今天就跟大家聊聊有關(guān)spring中@Transactional失效原因及解決辦法小結(jié),主要從三個方面考慮,具有一定的參考價值,感興趣的可以了解一下

spring事務(wù)@Transactional失效情況分析主要從以下幾個方面考慮:

1. mysql數(shù)據(jù)庫

默認(rèn)情況下mysql數(shù)據(jù)庫使用的是Innodb存儲引擎(5.5版本之后),它是支持事務(wù)的,但是如果你的表的存儲引擎是MyISAM,MyISAM是不支持事務(wù)的。這樣就會出現(xiàn)“事務(wù)失效”的問題了。

解決方案:修改存儲引擎為Innodb。

2. 業(yè)務(wù)代碼

2.1 執(zhí)行事務(wù)的Bean交由Spring管理

我們要使用Spring的申明式事務(wù),那么需要執(zhí)行事務(wù)的Bean是否已經(jīng)交由了Spring管理,在代碼中的體現(xiàn)就是類上是否有@Service、Component等一系列注解。

解決方案:將Bean交由Spring進(jìn)行管理(添加@Service注解)

2.2 非public的方法進(jìn)行事務(wù)管理

默認(rèn)情況下你無法使用@Transactional對一個非public的方法進(jìn)行事務(wù)管理

解決方案:修改需要事務(wù)管理的方法為public。

2.3 出現(xiàn)了自調(diào)用

多個方法都在同一個類中,其中第一個方法中調(diào)用了本類中的第二個和第三個方法,這就是自調(diào)用。

那么自調(diào)用為什么會導(dǎo)致事務(wù)失效呢?我們知道Spring中事務(wù)的實(shí)現(xiàn)是依賴于AOP的,當(dāng)容器在創(chuàng)建Service這個Bean時,發(fā)現(xiàn)這個類中存在了被@Transactional標(biāo)注的方法(修飾符為public)那么就需要為這個類創(chuàng)建一個代理對象并放入到容器中。由于方法實(shí)際上是由Service也就是目標(biāo)類自己調(diào)用的,所以在方法的前后并不會執(zhí)行事務(wù)的相關(guān)操作。這也是自調(diào)用帶來問題的根本原因:自調(diào)用時,調(diào)用的是目標(biāo)類中的方法而不是代理類中的方法。

解決方案

  • 自己注入自己,然后顯示的調(diào)用,
  • 這種方案看起來不是很優(yōu)雅
  • 利用AopContext,如下:
@Service
public class DemoService {
	@Transactional
	public void save(A a, B b) {
		((DemoService) AopContext.currentProxy()).saveB(b);
	}
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void saveB(B b){
		dao.saveB(a);
	}
}

使用上面這種解決方案需要注意的是,需要在配置類上新增一個配置

// exposeProxy=true代表將代理類放入到線程上下文中,默認(rèn)是false
@EnableAspectJAutoProxy(exposeProxy = true)

3. 事務(wù)回滾相關(guān)問題

3.1 該回滾的時候事務(wù)提交了

這種情況往往是程序員對Spring中事務(wù)的rollbackFor屬性不夠了解導(dǎo)致的。

Spring默認(rèn)拋出了未檢查unchecked異常(繼承自 RuntimeException 的異常)或者 Error才回滾事務(wù);其他異常不會觸發(fā)回滾事務(wù),已經(jīng)執(zhí)行的SQL會提交掉。如果在事務(wù)中拋出其他類型的異常,但卻期望 Spring 能夠回滾事務(wù),就需要指定rollbackFor屬性。

默認(rèn)情況下,只有出現(xiàn)RuntimeException或者Error才會回滾

public boolean rollbackOn(Throwable ex) {
? ? return (ex instanceof RuntimeException || ex instanceof Error);
}

所以,如果你想在出現(xiàn)了非RuntimeException或者Error時也回滾,請指定回滾時的異常,例如:

@Transactional(rollbackFor = Exception.class)

3.2 該提交的事務(wù)被回滾

對應(yīng)的異常信息如下:

Transaction rolled back because it has been marked as rollback-only

總結(jié)起來,主要的原因就是因?yàn)閮?nèi)部事務(wù)回滾時將整個大事務(wù)做了一個rollbackOnly的標(biāo)記,所以即使我們在外部事務(wù)中catch了拋出的異常,整個事務(wù)仍然無法正常提交,并且如果你希望正常提交,Spring還會拋出一個異常。

3.3 解決方案

這個解決方案要依賴業(yè)務(wù)而定,你要明確你想要的結(jié)果是什么

內(nèi)部事務(wù)發(fā)生異常,外部事務(wù)catch異常后,內(nèi)部事務(wù)自行回滾,不影響外部事務(wù)
將內(nèi)部事務(wù)的傳播級別設(shè)置為nested/requires_new均可。在我們的例子中就是做如下修改:

// @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
@Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)
public void a() throws ClassNotFoundException{
    // ......
    throw new ClassNotFoundException();
}

雖然這兩者都能得到上面的結(jié)果,但是它們之間還是有不同的。當(dāng)傳播級別為requires_new時,兩個事務(wù)完全沒有聯(lián)系,各自都有自己的事務(wù)管理機(jī)制(開啟事務(wù)、關(guān)閉事務(wù)、回滾事務(wù))。但是傳播級別為nested時,實(shí)際上只存在一個事務(wù),只是在調(diào)用a方法時設(shè)置了一個保存點(diǎn),當(dāng)a方法回滾時,實(shí)際上是回滾到保存點(diǎn)上,并且當(dāng)外部事務(wù)提交時,內(nèi)部事務(wù)才會提交,外部事務(wù)如果回滾,內(nèi)部事務(wù)會跟著回滾。

 內(nèi)部事務(wù)發(fā)生異常時,外部事務(wù)catch異常后,內(nèi)外兩個事務(wù)都回滾,但是方法不拋出異常

4. 讀寫分離跟事務(wù)結(jié)合使用時的問題

讀寫分離一般有兩種實(shí)現(xiàn)方式

  • 配置多數(shù)據(jù)源
  • 依賴中間件

如果是配置了多數(shù)據(jù)源的方式實(shí)現(xiàn)了讀寫分離,那么需要注意的是:如果開啟了一個讀寫事務(wù),那么必須使用寫節(jié)點(diǎn),如果是一個只讀事務(wù),那么可以使用讀節(jié)點(diǎn)。

如果是依賴于中間件那么需要注意:需要根據(jù)中間件的事務(wù)規(guī)范使用事務(wù)。

到此這篇關(guān)于spring事務(wù)@Transactional失效原因及解決辦法小結(jié)的文章就介紹到這了,更多相關(guān)spring @Transactional失效內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java多線程之線程的創(chuàng)建

    Java多線程之線程的創(chuàng)建

    這篇文章主要介紹了Java多線程之線程的創(chuàng)建,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • struts2簡介_動力節(jié)點(diǎn)Java學(xué)院整理

    struts2簡介_動力節(jié)點(diǎn)Java學(xué)院整理

    Struts2框架是MVC流程框架,適合分層開發(fā),這篇文章主要為大家詳細(xì)介紹了struts2簡介的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • Java并發(fā)編程之線程中斷

    Java并發(fā)編程之線程中斷

    這篇文章主要介紹了Java并發(fā)編程線程中斷,java線程中斷是一種線程間的協(xié)作模式,通過設(shè)置線程的中斷標(biāo)志并不能直接終止該線程的運(yùn)行,而是被中斷的線程根據(jù)中斷狀態(tài)自行處理,需要的朋友可以參考一下
    2021-09-09
  • ThreadLocal常用方法、使用場景及注意事項(xiàng)說明

    ThreadLocal常用方法、使用場景及注意事項(xiàng)說明

    這篇文章主要介紹了ThreadLocal常用方法、使用場景及注意事項(xiàng)說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringCloud Feign原理剖析

    SpringCloud Feign原理剖析

    feign是用在微服務(wù)中,各個微服務(wù)間的調(diào)用,它是通過聲明式的方式來定義接口,而不用實(shí)現(xiàn)接口,feign讓服務(wù)間的調(diào)用變得簡單,不用各個服務(wù)去處理http client相關(guān)的邏輯,本文詳細(xì)介紹SpringCloud Feign原理,需要的朋友可以參考下
    2023-06-06
  • Java Swing SpringLayout彈性布局的實(shí)現(xiàn)代碼

    Java Swing SpringLayout彈性布局的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Java Swing SpringLayout彈性布局的實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • idea設(shè)置在包里面在創(chuàng)建一個包方式

    idea設(shè)置在包里面在創(chuàng)建一個包方式

    這篇文章主要介紹了idea設(shè)置在包里面在創(chuàng)建一個包方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • SpringBoot自動重啟的兩種方法

    SpringBoot自動重啟的兩種方法

    我們在項(xiàng)目開發(fā)階段,可能經(jīng)常會修改代碼,修改完后就要重啟Spring Boot,本文主要介紹了SpringBoot自動重啟的兩種方法,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • springboot自帶的緩存@EnableCaching用法

    springboot自帶的緩存@EnableCaching用法

    這篇文章主要介紹了springboot自帶的緩存@EnableCaching用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 全鏈路監(jiān)控平臺Pinpoint?SkyWalking?Zipkin選型對比

    全鏈路監(jiān)控平臺Pinpoint?SkyWalking?Zipkin選型對比

    這篇文章主要為大家介紹了全鏈路監(jiān)控平臺Pinpoint?SkyWalking?Zipkin實(shí)現(xiàn)的選型對比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03

最新評論

浦江县| 马边| 嘉鱼县| 海原县| 云梦县| 西宁市| 隆德县| 商南县| 温宿县| 拉萨市| 剑河县| 晴隆县| 康马县| 揭阳市| 卫辉市| 五大连池市| 靖安县| 桐乡市| 辽源市| 武山县| 黄大仙区| 溧阳市| 耿马| 墨玉县| 无为县| 怀来县| 百色市| 正定县| 德江县| 蛟河市| 长乐市| 龙陵县| 孟津县| 洱源县| 锡林郭勒盟| 加查县| 长泰县| 丹巴县| 麦盖提县| 开阳县| 山西省|