Java學習-------事務失效

????????在 Java 開發中,事務是保證數據一致性和完整性的關鍵機制,尤其在涉及多步數據庫操作的業務場景中不可或缺。然而,在實際開發過程中,事務常常會出現 “失效” 的情況 —— 預期的回滾沒有發生,數據出現不一致。

????????Java 事務(尤其是基于 Spring 的聲明式事務)的正常運作依賴于一系列底層機制和約定,當這些機制被破壞或約定未被遵守時,就會導致事務失效。核心原因可歸納為以下幾類:?

(1)事務傳播行為配置不當:事務傳播行為決定了多個事務方法相互調用時的執行規則,若配置錯誤(如使用PROPAGATION_SUPPORTS或PROPAGATION_NOT_SUPPORTED),會導致事務無法按預期生效。?

(2)異常處理不當:事務默認只對未捕獲的RuntimeException及其子類異常回滾,若異常被手動捕獲且未重新拋出,或拋出的是受檢異常,會導致事務不回滾。?

(3)方法訪問權限問題:Spring 事務基于 AOP 動態代理實現,若目標方法是private、final或static修飾的,代理無法生效,事務自然失效。?

(4)數據源未配置事務管理器:事務的管理依賴于事務管理器,若未為數據源正確配置PlatformTransactionManager,事務注解將無法發揮作用。?

(5)自調用問題:在同一個類中,一個非事務方法調用本類的事務方法時,由于未經過代理對象,事務會失效。?

? ? ? ? 通常有以下失效的場景:

????????場景一:事務傳播行為配置錯誤?

????????場景描述:當一個事務方法調用另一個事務方法時,若傳播行為設置不合理,可能導致事務無法正常回滾。例如,在嵌套業務中使用PROPAGATION_REQUIRES_NEW時,內層事務提交后,外層事務回滾不會影響內層;若使用PROPAGATION_SUPPORTS,則方法會跟隨當前事務(若不存在則不開啟事務)。?

代碼示例(錯誤):?

?

@Service
public class OrderService {@Autowiredprivate PaymentService paymentService;@Transactional(propagation = Propagation.REQUIRED)public void createOrder() {// 保存訂單saveOrder();// 調用支付方法,傳播行為為SUPPORTSpaymentService.makePayment();}
}@Service
public class PaymentService {@Transactional(propagation = Propagation.SUPPORTS)public void makePayment() {// 支付邏輯,若當前無事務則不開啟事務updatePaymentStatus();// 模擬異常int i = 1 / 0;}
}

????????問題分析:makePayment方法的傳播行為為SUPPORTS,若createOrder的事務未生效(或傳播行為不匹配),則支付操作不會在事務中執行,異常發生后無法回滾。?

????????解決方法:根據業務需求選擇合適的傳播行為,如核心業務使用REQUIRED(默認值),確保方法在事務中執行。?

????????場景二:異常被捕獲但未重新拋出?

????????場景描述:事務方法中若手動捕獲了異常且未重新拋出,Spring 會認為事務執行成功,不會觸發回滾。?

代碼示例(錯誤):?

?

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;@Transactionalpublic void updateUserInfo() {try {userMapper.updateName(1, "newName");// 模擬異常int i = 1 / 0;} catch (Exception e) {// 僅捕獲異常未處理log.error("更新失敗", e);}}
}

????????問題分析:異常被try-catch捕獲后,未拋出到外層,Spring 無法感知異常,因此不會回滾updateName操作。?

????????解決方法:捕獲異常后重新拋出,或通過@Transactional(rollbackFor = Exception.class)指定回滾異常類型,并在外層處理。?

????????場景三:方法訪問權限問題?

????????場景描述:Spring 事務基于 AOP 動態代理實現,若事務方法被private、final或static修飾,代理無法重寫該方法,導致事務注解失效。?

代碼示例(錯誤):?

@Service
public class ProductService {@Autowiredprivate ProductMapper productMapper;// private修飾的事務方法@Transactionalprivate void reduceStock(Long productId, int quantity) {productMapper.decreaseStock(productId, quantity);}public void processOrder(Long productId, int quantity) {reduceStock(productId, quantity); // 調用私有方法}
}

?????????問題分析:reduceStock為私有方法,Spring 無法生成代理方法,@Transactional注解失效,庫存減少操作在異常發生時不會回滾。?

????????解決方法:將事務方法修改為public修飾,且避免使用final或static。?

????????場景四:未配置事務管理器?

????????場景描述:Spring 事務的生效依賴于事務管理器(如DataSourceTransactionManager),若未在配置類中聲明事務管理器,@Transactional注解將不起作用。?

????????代碼示例(錯誤配置):?

@Configuration
@MapperScan("com.example.mapper")
public class MyBatisConfig {@Beanpublic DataSource dataSource() {// 配置數據源HikariConfig config = new HikariConfig();config.setJdbcUrl("jdbc:mysql://localhost:3306/test");return new HikariDataSource(config);}
}

????????問題分析:僅配置了數據源,未配置PlatformTransactionManager,Spring 無法管理事務。?

????????解決方法:添加事務管理器配置:?

????????場景五:同一類內方法自調用?

????????場景描述:在同一個類中,非事務方法直接調用本類的事務方法時,由于調用的是原始對象(非代理對象),事務會失效。?

????????代碼示例(錯誤):?

@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;public void createOrder() {// 非事務方法調用本類事務方法saveOrder();}@Transactionalpublic void saveOrder() {orderMapper.insert(new Order());int i = 1 / 0; // 模擬異常}
}

問題分析:createOrder未被@Transactional修飾,調用saveOrder時使用的是當前類實例(非代理對象),事務注解失效,異常發生后訂單數據仍會被插入。?

解決方法:?

(1)將事務方法拆分到另一個服務類中,通過依賴注入調用(推薦)。?

(2)自注入代理對象(需開啟exposeProxy = true):?

?

? ? ? ? 在這里,給出幾個關于事務失效的排查建議?

(1)檢查事務注解:確保方法被@Transactional修飾,且注解屬性(如rollbackFor、propagation)配置正確。?

(2)驗證代理模式:Spring 默認使用 JDK 動態代理(接口),若使用 CGLIB 代理需確保類未被final修飾,且依賴中包含 CGLIB 庫。?

(3)查看異常處理:檢查事務方法中是否有異常被捕獲后未重新拋出,確保異常類型符合rollbackFor配置。?

(4)調試事務日志:在application.properties中添加日志配置logging.level.org.springframework.transaction=DEBUG,觀察事務的開啟、提交和回滾日志。?

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

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

相關文章

JavaScript 01 JavaScript 是什么

1.1 JavaScript 是什么JavaScript 是一門世界上最流行的腳本語言(基本所有平臺的所有軟件都會用到它)。“1994年,網景公司(Netscape)發布了Navigator瀏覽器0.9版。這是歷史上第一個比較成熟的網絡瀏覽器,轟動一時。但是&#xff0…

Bun v1.2.19發布,node_modules隔離,sql比node快6倍

大家好,我是農村程序員,獨立開發者,行業觀察員,前端之虎陳隨易。我會在這里分享關于 獨立開發、編程技術、思考感悟 等內容,歡迎關注。 技術群與交朋友請在個人網站聯系我,網站 1??:https://chensuiyi.me,網站 2??:https://me.yicode.tech。 如果你覺得本文有用…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - 主頁布局實現

大家好,我是java1234_小鋒老師,最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程,持續更新中,計劃月底更新完,感謝支持。今天講解主頁布局實現 視頻在線地址: …

# 微調需要準備哪些環境配置?

微調需要準備哪些環境配置? 如果沒有 GPU,即便是微調較小的大語言模型(LLMs),過程也會比較慢。如果你已經有了現成的 GPU,那就可以直接開工了。不過,并不是所有人都能負擔得起 GPU—— 這種情況…

ClickHouse物化視圖避坑指南:原理、數據遷移與優化

摘要ClickHouse物化視圖通過預計算和自動更新機制,顯著提升大數據分析查詢性能,尤其適合高并發聚合場景。本文將深入解析其技術原理、生產實踐中的優化策略,以及數據遷移的實戰經驗。一、物化視圖核心概念ClickHouse的物化視圖(Materialized …

Springboot3整合Elasticsearch8(elasticsearch-java)

1、Elasticsearch的JAVA客戶端選擇 Elasticsearch官方支持的客戶端 客戶端名稱簡介使用建議Elasticsearch Java API Client(新客戶端)官方推薦的新客戶端,基于 JSON Mapping(如 ElasticsearchClient 類),…

OpenCV 官翻8 - 其他算法

文章目錄高動態范圍成像引言曝光序列源代碼示例圖像說明結果色調映射圖像曝光融合附加資源高級圖像拼接 API(Stitcher 類)目標代碼說明相機模型試用指南圖像拼接詳解 (Python OpenCV >4.0.1)stitching_detailed如何使用背景減除方法目標代碼代碼解析結…

2025年一區SCI-回旋鏢氣動橢圓優化算法Boomerang Aerodynamic Ellipse-附Matlab免費代碼

引言 本期介紹一種新的元啟發式算法——回旋鏢氣動橢圓優化算法Boomerang Aerodynamic Ellipse Optimizer (BAEO)。該優化器的靈感來自于飛行中的回旋鏢的空氣動力學行為,明確地建模了釋放角和發射力如何塑造其軌跡。于2025年7月最新發表在JCR 1區,中科…

Custom SRP - Custom Render Pipeline

https://catlikecoding.com/unity/tutorials/custom-srp/custom-render-pipeline/ 1. 新建 Render Pipeline 任何內容的渲染,最終都是要由 unity 決定在哪里,什么時候,以哪些參數進行渲染。根據目標效果的復雜程度,決定渲染的過程…

C語言面向對象編程

1.內核通用鏈表一、什么是 list_head&#xff1f;list_head 是 Linux 內核中自己實現的一種 雙向循環鏈表 的結構&#xff0c;定義在 <linux/list.h> 中。它設計得非常輕巧、靈活&#xff0c;廣泛用于內核模塊、驅動、進程調度、網絡協議棧等。它的關鍵思想是&#xff1a…

Spring Boot+Redis Zset:三步構建高可靠延遲隊列系統

系統設計架構圖---------------- ----------------- ---------------- | | | | | | | 生產者 |------>| Redis ZSet |------>| 定時任務消費者 | | (添加延遲任務) | | (延…

MCP vs 傳統集成方案:REST API、GraphQL、gRPC的終極對比

MCP vs 傳統集成方案&#xff1a;REST API、GraphQL、gRPC的終極對比 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般絢爛的技術棧中&#xff0c;我是那個永不停歇的色彩收集者。 &#x1f98b; 每一個優化都是我培育的花朵&#xff0c;每一個特…

SQL語句中鎖的使用與優化

一、鎖機制簡介1.定義在數據庫中&#xff0c;除了傳統的計算資源&#xff08;如CPU、RAM、I/O等&#xff09;的爭用以外&#xff0c;數據也是一種供需要用戶共享的資源。如何保證數據并發訪問的一致性、有效性是所有數據庫必須解決的一個問題&#xff0c;鎖沖突也是影響數據庫并…

Linux筆記1——簡介安裝

操作系統給用戶一個操作界面&#xff0c;用戶通過操作界面使用系統資源Linux內核管理控制硬件&#xff0c;和硬件打交道SCSI&#xff08;盤&#xff09;sd**;第一個*表示磁盤順序&#xff0c;第二個*表示分區。例如&#xff1a;sda\sdb\sdc,sda1,sda2NVMe&#xff08;盤&#x…

GoLand 部署第一個項目

前言&#xff1a;Go環境部署分為兩種模式&#xff0c;一種是基于GOPATH部署&#xff08;老版本&#xff09;&#xff0c;另一種是基于Module部署&#xff08;新版本v1.11開始&#xff09;。GOPATH&#xff1a;需要配置GOPATH路徑&#xff0c;將GOPATH目錄視為工作目錄&#xff…

Mosaic數據增強介紹

1. 核心概念與目標Mosaic 是一種在計算機視覺&#xff08;尤其是目標檢測任務&#xff09;中非常流行且強大的數據增強技術。它最早由 Ultralytics 的 Alexey Bochkovskiy 在 YOLOv4 中提出并推廣&#xff0c;后來被廣泛應用于 YOLOv5, YOLOv7, YOLOv8 等模型以及其他目標檢測框…

LINUX 722 邏輯卷快照

邏輯卷快照 lvcreate -L 128M -s -n lv1-snap /dev/vg1/lv1 lvs lvscan mount -o ro /dev/vg1/lv1 /mmt/lv1-snap dmsetup ls --tree 測試 lvs /dev/vg1/lv1-snap dd if/dev/zero of/uc1/test bs1M count40 lvs /dev/vg1/lv1-snap 問題 [rootweb ~]# cd /mnt [rootweb mnt]# m…

Springboot+vue個人健康管理系統的設計與實現

文章目錄前言詳細視頻演示具體實現截圖后端框架SpringBoot前端框架Vue持久層框架MyBaits成功系統案例&#xff1a;代碼參考數據庫源碼獲取前言 博主介紹:CSDN特邀作者、985高校計算機專業畢業、現任某互聯網大廠高級全棧開發工程師、Gitee/掘金/華為云/阿里云/GitHub等平臺持續…

數據結構 --棧和隊鏈

一.棧的概念一種特殊的線性表&#xff0c;只能從固定的一端插入和刪除元素。棧中元素遵循先進后出的原則。二.模擬實現public class MyStack {public int size;public int[] array;public MyStack(){array new int[10];}private void grow(){array Arrays.copyOf(array,array…

文檔處理控件TX Text Control系列教程:使用 C# .NET 將二維碼添加到 PDF 文檔

PDF 文檔通常是合同、發票、證書和報告的最終格式。盡管它們在設計上是靜態的&#xff0c;但用戶現在希望能夠與它們交互、驗證信息并直接從這些文件訪問數字服務。這時&#xff0c;二維碼就變得至關重要。 PDF 文檔中的二維碼將印刷或數字內容與動態在線體驗連接起來。用戶只需…