亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot事務(wù)失效問(wèn)題原因、場(chǎng)景與解決方案

 更新時(shí)間:2025年07月09日 09:40:06   作者:好奇的菜鳥(niǎo)  
在SpringBoot開(kāi)發(fā)中,事務(wù)管理是保證數(shù)據(jù)一致性和完整性的核心機(jī)制,然而,許多開(kāi)發(fā)者在使用@Transactional注解時(shí),可能會(huì)遇到事務(wù)失效的問(wèn)題,導(dǎo)致數(shù)據(jù)異?;驑I(yè)務(wù)邏輯錯(cuò)誤,本文將深入分析SpringBoot中事務(wù)失效的常見(jiàn)原因,并結(jié)合實(shí)際場(chǎng)景給出解決方案

一、事務(wù)失效的常見(jiàn)場(chǎng)景

1.1 同類(lèi)中方法直接調(diào)用導(dǎo)致事務(wù)失效

原因分析

Spring 的事務(wù)是通過(guò) AOP 代理實(shí)現(xiàn)的,只有通過(guò)代理對(duì)象調(diào)用的方法,事務(wù)才會(huì)生效。如果在同一個(gè)類(lèi)中,一個(gè)方法直接調(diào)用另一個(gè)帶有 @Transactional 注解的方法(即 this.method() 方式),則事務(wù)不會(huì)生效。

示例代碼

@Service
public class UserService {

    @Transactional
    public void createUser(User user) {
        // 保存用戶(hù)
    }

    public void createUserAndLog(User user) {
        this.createUser(user); // 事務(wù)失效
        log.info("用戶(hù)創(chuàng)建成功");
    }
}

解決方案

  • 將事務(wù)方法提取到另一個(gè)類(lèi)中,通過(guò) Spring 注入調(diào)用。
  • 使用 AopContext.currentProxy() 獲取當(dāng)前代理對(duì)象調(diào)用方法。
  • 自我注入:將當(dāng)前 Service 注入到自身,通過(guò)注入的對(duì)象調(diào)用方法。

推薦方式(自我注入)

@Service
public class UserService {

    @Autowired
    private UserService self; // 自我注入

    @Transactional
    public void createUser(User user) {
        // 保存用戶(hù)
    }

    public void createUserAndLog(User user) {
        self.createUser(user); // 事務(wù)生效
        log.info("用戶(hù)創(chuàng)建成功");
    }
}

1.2 異常未被正確捕獲或拋出

原因分析

默認(rèn)情況下,Spring 只對(duì) RuntimeException 和 Error 進(jìn)行回滾。如果捕獲了異常但未拋出,或拋出了非運(yùn)行時(shí)異常,事務(wù)不會(huì)回滾。

示例代碼

@Transactional
public void updateUser(User user) {
    try {
        userRepository.save(user);
    } catch (Exception e) {
        log.error("更新失敗", e);
        // 異常被吞掉,事務(wù)不會(huì)回滾
    }
}

解決方案

  • @Transactional 注解中指定回滾的異常類(lèi)型。
  • 捕獲異常后,重新拋出 RuntimeException。

推薦方式

@Transactional(rollbackFor = Exception.class)
public void updateUser(User user) {
    try {
        userRepository.save(user);
    } catch (Exception e) {
        log.error("更新失敗", e);
        throw new RuntimeException("更新失敗", e);
    }
}

1.3 事務(wù)傳播行為配置不當(dāng)

原因分析

在嵌套事務(wù)中,如果內(nèi)層事務(wù)使用了 Propagation.REQUIRES_NEW,它會(huì)啟動(dòng)一個(gè)獨(dú)立的新事務(wù),外層事務(wù)的回滾不會(huì)影響內(nèi)層事務(wù),可能導(dǎo)致數(shù)據(jù)不一致。

示例代碼

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void innerMethod() {
    // 內(nèi)層事務(wù)
}

@Transactional
public void outerMethod() {
    innerMethod();
    throw new RuntimeException("外層異常");
}

問(wèn)題

  • 外層事務(wù)回滾,但內(nèi)層事務(wù)已提交,導(dǎo)致數(shù)據(jù)不一致。

解決方案

  • 根據(jù)業(yè)務(wù)需求選擇合適的傳播行為。
  • 如果希望內(nèi)外事務(wù)一致,避免使用 REQUIRES_NEW,改用 REQUIRED。

推薦方式

@Transactional(propagation = Propagation.REQUIRED)
public void innerMethod() {
    // 內(nèi)層事務(wù)
}

@Transactional
public void outerMethod() {
    innerMethod();
    throw new RuntimeException("外層異常");
}

1.4 數(shù)據(jù)庫(kù)引擎不支持事務(wù)

原因分析

某些數(shù)據(jù)庫(kù)引擎(如 MySQL 的 MyISAM)不支持事務(wù),即使代碼中配置了事務(wù),也不會(huì)生效。

解決方案

  • 確保數(shù)據(jù)庫(kù)使用支持事務(wù)的引擎,如 InnoDB

1.5 事務(wù)管理器未正確配置

原因分析

如果項(xiàng)目中沒(méi)有正確配置事務(wù)管理器,@Transactional 注解不會(huì)生效。

解決方案

  • 確保在配置類(lèi)中配置了事務(wù)管理器,例如:
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

1.6 多數(shù)據(jù)源事務(wù)管理問(wèn)題

原因分析

在多數(shù)據(jù)源場(chǎng)景下,如果沒(méi)有為每個(gè)數(shù)據(jù)源配置獨(dú)立的事務(wù)管理器,事務(wù)可能會(huì)失效。

解決方案

  • 為每個(gè)數(shù)據(jù)源配置獨(dú)立的事務(wù)管理器。
  • 使用 @Transactional(value = "transactionManagerName") 指定事務(wù)管理器。

二、如何排查事務(wù)失效問(wèn)題

2.1 啟用事務(wù)日志

application.properties 中開(kāi)啟事務(wù)日志:

logging.level.org.springframework.transaction=DEBUG
logging.level.org.springframework.jdbc=DEBUG

2.2 檢查代理對(duì)象

確保事務(wù)方法是通過(guò) Spring 的代理對(duì)象調(diào)用的,而不是直接調(diào)用。

2.3 檢查異常處理

確保異常被正確拋出,并符合事務(wù)回滾的條件。

2.4 檢查數(shù)據(jù)庫(kù)引擎

確保數(shù)據(jù)庫(kù)引擎支持事務(wù),例如使用 InnoDB。

三、事務(wù)傳播行為(Propagation)的常用類(lèi)型

傳播行為類(lèi)型說(shuō)明
REQUIRED(默認(rèn))當(dāng)前方法加入已有事務(wù),若沒(méi)有則創(chuàng)建新事務(wù)。
REQUIRES_NEW創(chuàng)建新事務(wù),并掛起當(dāng)前事務(wù)。
NOT_SUPPORTED不支持事務(wù),掛起當(dāng)前事務(wù)。
NEVER不允許事務(wù),若當(dāng)前有事務(wù)則拋出異常。
SUPPORTS當(dāng)前方法可以在事務(wù)中執(zhí)行,也可以不在事務(wù)中執(zhí)行。
MANDATORY當(dāng)前方法必須在事務(wù)中執(zhí)行,若沒(méi)有事務(wù)則拋出異常。

四、總結(jié)

Spring Boot 中的事務(wù)失效問(wèn)題,通常是由于以下原因?qū)е碌模?/p>

  • 同類(lèi)中方法直接調(diào)用。
  • 異常未被正確拋出。
  • 事務(wù)傳播行為配置不當(dāng)。
  • 數(shù)據(jù)庫(kù)引擎不支持事務(wù)
  • 事務(wù)管理器未正確配置。
  • 多數(shù)據(jù)源事務(wù)管理問(wèn)題。

為了避免事務(wù)失效,建議遵循以下最佳實(shí)踐:

  • 確保事務(wù)方法通過(guò) Spring 代理調(diào)用。
  • 正確處理異常,確保事務(wù)回滾。
  • 合理配置事務(wù)傳播行為。
  • 使用支持事務(wù)的數(shù)據(jù)庫(kù)引擎
  • 正確配置事務(wù)管理器。

通過(guò)本文的分析和解決方案,相信大家對(duì) Spring Boot 的事務(wù)管理有了更深入的理解。在實(shí)際開(kāi)發(fā)中,合理使用事務(wù),能夠有效保證數(shù)據(jù)的一致性和完整性。

以上就是SpringBoot事務(wù)失效問(wèn)題原因、場(chǎng)景與解決方案的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot事務(wù)失效問(wèn)題的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot項(xiàng)目jar發(fā)布后如何獲取jar包所在目錄路徑

    SpringBoot項(xiàng)目jar發(fā)布后如何獲取jar包所在目錄路徑

    這篇文章主要介紹了SpringBoot項(xiàng)目jar發(fā)布后如何獲取jar包所在目錄路徑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java實(shí)現(xiàn)隨機(jī)生成大小寫(xiě)混合的卡密的步驟

    Java實(shí)現(xiàn)隨機(jī)生成大小寫(xiě)混合的卡密的步驟

    在現(xiàn)代軟件開(kāi)發(fā)中,生成隨機(jī)卡密是一個(gè)常見(jiàn)的需求,尤其是在需要為用戶(hù)生成唯一識(shí)別碼或安全令牌的場(chǎng)景中,卡密通常由數(shù)字和字母組成,有時(shí)還會(huì)包含特殊字符,本文通過(guò)代碼講解的非常詳細(xì),需要的朋友可以參考下
    2024-11-11
  • SpringMVC中RequestContextHolder獲取請(qǐng)求信息的方法

    SpringMVC中RequestContextHolder獲取請(qǐng)求信息的方法

    這篇文章主要介紹了SpringMVC中RequestContextHolder獲取請(qǐng)求信息的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Centos中安裝jdk案例講解

    Centos中安裝jdk案例講解

    這篇文章主要介紹了Centos中安裝jdk案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java中使用@CrossOrigin和Proxy解決跨域問(wèn)題詳解

    Java中使用@CrossOrigin和Proxy解決跨域問(wèn)題詳解

    這篇文章主要介紹了Java中使用@CrossOrigin和Proxy解決跨域問(wèn)題詳解,在Web開(kāi)發(fā)中,如果前端頁(yè)面和后端接口不在同一個(gè)域名下,就會(huì)發(fā)生跨域請(qǐng)求的問(wèn)題,同源策略是瀏覽器的一種安全策略,它限制了來(lái)自不同源的客戶(hù)端腳本在瀏覽器中運(yùn)行時(shí)的交互,需要的朋友可以參考下
    2023-12-12
  • 在Java的Struts中判斷是否調(diào)用AJAX及用攔截器對(duì)其優(yōu)化

    在Java的Struts中判斷是否調(diào)用AJAX及用攔截器對(duì)其優(yōu)化

    這篇文章主要介紹了在Java的Struts中判斷是否調(diào)用AJAX及用攔截器對(duì)其優(yōu)化的方法,Struts框架是Java的SSH三大web開(kāi)發(fā)框架之一,需要的朋友可以參考下
    2016-01-01
  • MyBatis/mybatis-plus項(xiàng)目打印SQL的方法實(shí)現(xiàn)

    MyBatis/mybatis-plus項(xiàng)目打印SQL的方法實(shí)現(xiàn)

    SpringBoot項(xiàng)目中,經(jīng)常需要打印SQL語(yǔ)句及其參數(shù),本文就來(lái)介紹一下MyBatis/mybatis-plus項(xiàng)目打印SQL的方法實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • SpringCloud及Nacos服務(wù)注冊(cè)IP選擇問(wèn)題解決方法

    SpringCloud及Nacos服務(wù)注冊(cè)IP選擇問(wèn)題解決方法

    這篇文章主要介紹了SpringCloud及Nacos服務(wù)注冊(cè)IP選擇問(wèn)題,為什么注冊(cè)的IP和真實(shí)IP不符合呢,原因是Nacos客戶(hù)端在注冊(cè)服務(wù)時(shí)會(huì)從機(jī)器網(wǎng)卡中選擇一個(gè)IP來(lái)注冊(cè),所以,當(dāng)注冊(cè)了的是非真實(shí)IP后,另一臺(tái)機(jī)器調(diào)用時(shí)是不可能調(diào)通的,知道問(wèn)題原因就是解決方法,一起看看吧
    2024-01-01
  • Java 是如何讀取和寫(xiě)入瀏覽器Cookies的實(shí)例詳解

    Java 是如何讀取和寫(xiě)入瀏覽器Cookies的實(shí)例詳解

    這篇文章主要介紹了Java 是如何讀取和寫(xiě)入瀏覽器Cookies的實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • SSH框架網(wǎng)上商城項(xiàng)目第13戰(zhàn)之Struts2文件上傳功能

    SSH框架網(wǎng)上商城項(xiàng)目第13戰(zhàn)之Struts2文件上傳功能

    這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第13戰(zhàn)之Struts2文件上傳功能的相關(guān)資料,感興趣的小伙伴們可以參考一下
    2016-06-06

最新評(píng)論