Spring 事務失效的7種場景, 事務失效后如何進行處理

文章目錄

  • 簡單說說spring事務失效的場景
    • Spring 事務失效的7種場景
        • 1.1、未啟用[spring事務管理](https://so.csdn.net/so/search?q=spring事務管理&spm=1001.2101.3001.7020)功能
        • 1.2、方法不是public類型的
        • 1.3、數據源未配置事務管理器
        • 1.4、自身調用問題
        • 1.5、異常類型錯誤
        • 1.6、異常被吞了
        • 1.7、業務和spring事務代碼必須在一個線程中
        • 2、如何快速定位事務相關bug?

簡單說說spring事務失效的場景

Spring 事務失效的7種場景

  1. 未啟用spring事務管理功能
  2. 方法不是public類型的
  3. 數據源未配置事務管理器
  4. 自身調用問題
  5. 異常類型錯誤
  6. 異常被吞了
  7. 業務和spring事務代碼必須在一個線程中

1、數據庫不支持事務

2、沒有配置事務管理器

3、事務所在的方法沒有被public修飾

4、異常被catch,沒有拋出,事務會失效

5、異常類型錯誤,默認是runtimeException才會回滾的

? 解決方案:加上@Transactional(rollbackFor = Exception.class)注解;這樣Exception也會回滾

6、用final或者static關鍵字修飾的方法事務會失效

7、事務需要從外部調用,Spring 自調事務用會失效。即相同類里邊,A 方法沒有事務,B 方法有事務,A 方法調用 B 方法,則 B 方法的事務會失效,這點尤其要注意,因為代理模式只攔截通過代理傳入的外部方法調用,所以自調用事務是不生效的。

1.1、未啟用spring事務管理功能

@EnableTransactionManagement 注解用來啟用spring事務自動管理事務的功能,這個注解千萬不要忘記寫了。

1.2、方法不是public類型的

@Transaction 可以用在類上、接口上、public方法上,如果將@Trasaction用在了非public方法上,事務將無效。

1.3、數據源未配置事務管理器

spring是通過事務管理器了來管理事務的,一定不要忘記配置事務管理器了,要注意為每個數據源配置一個事務管理器:

@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);
}
1.4、自身調用問題

spring是通過aop的方式,對需要spring管理事務的bean生成了代理對象,然后通過代理對象攔截了目標方法的執行,在方法前后添加了事務的功能,所以必須通過代理對象調用目標方法的時候,事務才會起效。

看下面代碼,大家思考一個問題:當外部直接調用m1的時候,m2方法的事務會生效么?

@Component
public class UserService {public void m1(){this.m2();}@Transactionalpublic void m2(){//執行db操作}
}

??顯然不會生效,因為m1中通過this的方式調用了m2方法,而this并不是代理對象,this.m2()不會被事務攔截器,所以事務是無效的,如果外部直接調用通過UserService這個bean來調用m2方法,事務是有效的,上面代碼可以做一下調整,如下,@1在UserService中注入了自己,此時m1中的m2事務是生效的.

@Component
public class UserService {@Autowired //@1private UserService userService;public void m1() {this.userService.m2();}@Transactionalpublic void m2() {//執行db操作}
}

重點:必須通過代理對象訪問方法,事務才會生效。

1.5、異常類型錯誤

spring事務回滾的機制:對業務方法進行try catch,當捕獲到有指定的異常時,spring自動對事務進行回滾,那么問題來了,哪些異常spring會回滾事務呢?

并不是任何異常情況下,spring都會回滾事務,默認情況下,RuntimeException和Error的情況下,spring事務才會回滾。

也可以自定義回滾的異常類型:

@Transactional(rollbackFor = {異常類型列表})
1.6、異常被吞了

當業務方法拋出異常,spring感知到異常的時候,才會做事務回滾的操作,若方法內部將異常給吞了,那么事務無法感知到異常了,事務就不會回滾了。

如下代碼,事務操作2發生了異常,但是被捕獲了,此時事務并不會被回滾

@Transactional
public void m1(){//事務操作1try{//事務操作2,內部拋出了異常}catch(Exception e){}
}
1.7、業務和spring事務代碼必須在一個線程中

?? spring事務實現中使用了ThreadLocal,ThreadLocal大家應該知道吧,可以實現同一個線程中數據共享,必須是同一個線程的時候,數據才可以共享,這就要求業務代碼必須和spring事務的源碼執行過程必須在一個線程中,才會受spring事務的控制,比如下面代碼,方法內部的子線程內部執行的事務操作將不受m1方法上spring事務的控制,這個大家一定要注意

@Transactional
public void m1() {new Thread() {//一系列事務操作}.start();
}
2、如何快速定位事務相關bug?

2種方式

方式1:看日志

如果你使用了logback或者log4j來輸出日志,可以修改一下日志級別為debug模式,可以看到事務的詳細執行日志,幫助你定位錯誤

方式2:調試代碼

如果你對源碼比較了解,那么你會知道被spring管理事務的業務方法,執行的時候都會被TransactionInterceptor攔截器攔截,會進入到它的invoke方法中,咱們可以在invoke方法中設置一些斷點,可以看到詳細的執行過程,排錯也就比較容易了。

整體上來說,還是需要你深入理解原理,原理了解了,寫代碼的時候本身就會避免很多坑。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/165339.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/165339.shtml
英文地址,請注明出處:http://en.pswp.cn/news/165339.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《golang設計模式》第三部分·行為型模式-07-觀察者模式(Observer)/發布者—訂閱者模式

文章目錄 1. 概念1.1 角色1.2 類圖 2. 代碼示例2.1 代碼2.2 類圖 1. 概念 觀察者(Observer)指當目標對象狀態發生變化后,對狀態變化事件進行響應或處理的對象。 1.1 角色 Subject(抽象主題): 它可以有多…

微服務實戰系列之Feign

前言 不知不覺,“微服務實戰系列”已完成了六篇,每篇都聚焦一個主題,目的是便于各位盆友能夠快速、全面地接收和消化。 博主從服務注冊到服務監控,從服務路由到服務安全,從身份認證到加密技術均有涉獵。凡此均有關微服…

Java核心知識點整理大全10-筆記

往期快速傳送門: Java核心知識點整理大全-筆記_希斯奎的博客-CSDN博客文章瀏覽閱讀9w次,點贊7次,收藏7次。Java核心知識點整理大全https://blog.csdn.net/lzy302810/article/details/132202699?spm1001.2014.3001.5501 Java核心知識點整理…

【LeetCode刷題】--67.二進制求和

67.二進制求和 方法:模擬計算 class Solution {public String addBinary(String a, String b) {StringBuilder ans new StringBuilder();int carry 0;for(int ia.length()-1,jb.length()-1;i>0||j>0;i--,j--){int sum carry;sum i >0 ? a.charAt(i) …

web:[WUSTCTF2020]樸實無華

題目 點開頁面顯示如下 頁面顯示了一行報錯:Cannot modify header information - headers already sent by (output started at /var/www/html/index.php:3) in /var/www/html/index.php on line 4 意思為不能修改報頭信息-報頭已經發送(輸出開始于/var/www/html/i…

vue3 websocket連接 發送數據

先建一個websocket.js放在項目中,內容如下: var websock null; let rec; //斷線重連后,延遲5秒重新創建WebSocket連接 rec用來存儲延遲請求的代碼 let isConnect false; //連接標識 避免重復連接 let checkMsg "heartbeat"; /…

MySQL與Redis如何保證數據的一致性

文章目錄 MySQL與Redis如何保證數據的一致性?不好的方案1. 先寫 MySQL,再寫 Redis2. 先寫 Redis,再寫 MySQL3. 先刪除 Redis,再寫 MySQL 好的方案4. 先刪除 Redis,再寫 MySQL,再刪除 Redis5. 先寫 MySQL&am…

C# 數據庫封裝

最近有些地方用到c#,研究了一下,也有數據庫方面的操作,那就繼續封裝,自己用起來好用一點。 數據庫連接 using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using Sys…

Leetcode算法系列| 1. 兩數之和(四種解法)

目錄 1.題目2.題解解法一:暴力枚舉解法二:哈希表解法解法三:雙指針(有序狀態)解法四:二分查找(有序狀態) 1.題目 給定一個整數數組 nums 和一個整數目標值 target,請你在該數組中找出 和為目標值 target 的那 兩個 整數…

『RabbitMQ』入門指南(安裝,配置,應用)

前言 RabbitMQ 是在 AMQP(Advanced Message Queuing Protocol) 協議標準基礎上完整的,可復用的企業消息系統。它遵循 Mozilla Public License 開源協議,采用 Erlang 實現的工業級的消息隊列(MQ)服務器,建立在 Erlang …

產品經理提問常用的ChatGPT通用提示詞模板

如何評估產品市場的潛力和可行性? 如何定義和明確產品的目標用戶和需求? 如何進行競品分析和比較,制定產品的差異化策略? 如何設計產品的功能和特性,滿足用戶需求? 如何制定產品的定價策略和銷售計劃&a…

qml View3D使用介紹

在Qt Quick 3D中,View3D 是一個用于展示 3D 內容的 QML 類型。View3D 允許你將 3D 場景集成到 Qt Quick 2D 用戶界面中,這意味著你可以在傳統的 2D UI 元素(如按鈕、文本和圖像)與 3D 圖形之間無縫地進行整合。 View3D 提供了一個視口,用于渲染 3D 場景。它可以包括多個 …

HTTPS攻擊怎么防御?

HTTPS 簡介 超文本傳輸安全協議( HTTPS )是一種通過計算機網絡進行安全通信的傳輸協議。HTTPS 經由 HTTP 進行通信,但利用 SSL/TLS 來加密數據包。 HTTPS 開發的主要目的,是提供對網站服務器的身份認證,保護交換數據的…

批量將本地N個英文Html文檔進行中文翻譯-操作篇

Unity3D特效百例案例項目實戰源碼Android-Unity實戰問題匯總游戲腳本-輔助自動化Android控件全解手冊再戰Android系列Scratch編程案例軟考全系列Unity3D學習專欄藍橋系列ChatGPT和AIGC 👉關于作者 專注于Android/Unity和各種游戲開發技巧,以及各種資源分…

QtCreator9.02不支持JDK11解決

最終效果 使用Android Studio 下載Android SDK Platform 31與Sources for Android 31 下載Android SDK Build Tools 31.0.0 下載NDK 25.1 ,23.1 ,21.3 重要: 下載Android SDK Command-Line Tools ,選擇10.0或者9.0其中一個版本 其它版本不支持JDK11 ,本例選擇10.0 下載CMak…

如何進行MySQL的主從復制(MySQL5.7)

背景:在一些Web服務器開發中,系統用戶在進行數據訪問時,基本都是直接操作數據庫MySQL進行訪問,而這種情況下,若只有一臺MySQL服務器,可能會存在如下問題 數據的讀和寫的所有壓力都會由一臺數據庫獨…

淺析jdk8所包含的主要特性

至今Java 8仍然是許多開發者首選的JDK版本,Java 8的生態系統非常成熟,許多庫和框架都已經適配了Java 8。遷移到新的Java版本可能需要重新評估和調整現有的依賴關系,這對于一些大型項目可能是一個挑戰。那么Java 8有哪些特性讓多數開發者鐘愛呢…

西米支付:如何設計和構建游戲支付系統?

如何設計和構建游戲支付系統? 目前,游戲開發中最常見的支付方式包括微信支付、支付寶支付和蘋果支付等。今天,我將與大家分享游戲支付系統的架構和設計。 游戲支付的主要業務流程是指游戲玩家在游戲中購買虛擬物品或服務所進行的支付過程。一…

ElasticSearch 7 SQL 詳解

平時使用Elasticsearch的時候,會在Kibana中使用Query DSL來查詢數據.每次要用到Query DSL時都基本忘光了,需要重新在回顧一遍,最近發現Elasticsearch已經支持SQL查詢了(6.3版本以后),整理了下一些用法. 簡介 Elasticsearch SQL是一個X-Pack組件,它允許針對Elasticsearch實時執…

ESP32之避障

ESP32之避障 圖片 程序 int Led27;//定義LED 接口 int buttonpin4; //定義光遮斷傳感器接口 int val;//定義數字變量val void setup() { pinMode(Led,OUTPUT);//定義LED 為輸出接口 pinMode(buttonpin,INPUT);//定義避障傳感器為輸出接口 } void loop() {Serial.begin(9600);…