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

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

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

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

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

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

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

2. 業(yè)務代碼

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

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

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

2.2 非public的方法進行事務管理

默認情況下你無法使用@Transactional對一個非public的方法進行事務管理

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

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

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

那么自調(diào)用為什么會導致事務失效呢?我們知道Spring中事務的實現(xiàn)是依賴于AOP的,當容器在創(chuàng)建Service這個Bean時,發(fā)現(xiàn)這個類中存在了被@Transactional標注的方法(修飾符為public)那么就需要為這個類創(chuàng)建一個代理對象并放入到容器中。由于方法實際上是由Service也就是目標類自己調(diào)用的,所以在方法的前后并不會執(zhí)行事務的相關(guān)操作。這也是自調(diào)用帶來問題的根本原因:自調(diào)用時,調(dià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代表將代理類放入到線程上下文中,默認是false
@EnableAspectJAutoProxy(exposeProxy = true)

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

3.1 該回滾的時候事務提交了

這種情況往往是程序員對Spring中事務的rollbackFor屬性不夠了解導致的。

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

默認情況下,只有出現(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 該提交的事務被回滾

對應的異常信息如下:

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

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

3.3 解決方案

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

內(nèi)部事務發(fā)生異常,外部事務catch異常后,內(nèi)部事務自行回滾,不影響外部事務
將內(nèi)部事務的傳播級別設(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é)果,但是它們之間還是有不同的。當傳播級別為requires_new時,兩個事務完全沒有聯(lián)系,各自都有自己的事務管理機制(開啟事務、關(guān)閉事務、回滾事務)。但是傳播級別為nested時,實際上只存在一個事務,只是在調(diào)用a方法時設(shè)置了一個保存點,當a方法回滾時,實際上是回滾到保存點上,并且當外部事務提交時,內(nèi)部事務才會提交,外部事務如果回滾,內(nèi)部事務會跟著回滾。

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

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

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

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

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

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

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

相關(guān)文章

  • SpringBoot yaml語法與數(shù)據(jù)讀取操作詳解

    SpringBoot yaml語法與數(shù)據(jù)讀取操作詳解

    YAML 是 “YAML Ain’t Markup Language”(YAML 不是一種標記語言)的遞歸縮寫。在開發(fā)的這種語言時,YAML 的意思其實是:“Yet Another Markup Language”(仍是一種標記語言),本文給大家介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • MyBatisPlus分頁的同時指定排序規(guī)則說明

    MyBatisPlus分頁的同時指定排序規(guī)則說明

    這篇文章主要介紹了MyBatisPlus分頁的同時指定排序規(guī)則說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • java對接支付寶支付接口開發(fā)詳細步驟

    java對接支付寶支付接口開發(fā)詳細步驟

    本文主要介紹了java對接支付寶支付接口開發(fā)詳細步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 使用SpringBoot請求參數(shù)過濾空格

    使用SpringBoot請求參數(shù)過濾空格

    這篇文章主要介紹了使用SpringBoot請求參數(shù)過濾空格的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot 如何自定義項目啟動信息打印

    SpringBoot 如何自定義項目啟動信息打印

    這篇文章主要介紹了SpringBoot 如何自定義項目啟動信息打印方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java 引用類型的數(shù)據(jù)傳遞的是內(nèi)存地址實例

    java 引用類型的數(shù)據(jù)傳遞的是內(nèi)存地址實例

    這篇文章主要介紹了java 引用類型的數(shù)據(jù)傳遞的是內(nèi)存地址實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring MVC框架配置方法詳解

    Spring MVC框架配置方法詳解

    這篇文章主要為大家詳細介紹了Spring MVC框架的配置方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • 基于@RequestParam與@RequestBody使用對比

    基于@RequestParam與@RequestBody使用對比

    這篇文章主要介紹了@RequestParam與@RequestBody的使用對比,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java中基于注解的代碼生成工具MapStruct映射使用詳解

    Java中基于注解的代碼生成工具MapStruct映射使用詳解

    MapStruct?作為一個基于注解的代碼生成工具,為我們提供了一種更加優(yōu)雅、高效的解決方案,本文主要為大家介紹了它的具體使用,感興趣的可以了解下
    2025-02-02
  • SpringLDAP連接LDAPS證書報錯問題及解決

    SpringLDAP連接LDAPS證書報錯問題及解決

    這篇文章主要介紹了SpringLDAP連接LDAPS證書報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05

最新評論