Spring事務失效場景?

題目詳細答案

Spring事務失效的場景主要有以下幾種。

非public方法使用@Transactional

場景描述:Spring事務管理是基于AOP實現的,而AOP對于JDK動態代理CGLib動態代理只會代理public方法。如果事務方法的訪問修飾符為非public,SpringAOP無法正確地代理該方法,從而導致事務失效。

示例代碼:事務方法的訪問修飾符被設置為private、default或protected。

解決方案:將需要事務管理的方法設置為public。

在同類中的非事務方法調用事務方法

場景描述:Spring的事務管理是通過動態代理實現的,只有通過代理對象調用的方法才能享受到Spring的事務管理。如果在同一個類中,一個沒有標記為@Transactional的方法內部調用了一個標記為@Transactional的方法,那么事務是不會起作用的。

解決方案:盡量將事務方法放在不同的類中,或者使用Spring的AopContext.currentProxy()來獲取當前類的代理對象,然后通過代理對象調用事務方法。

事務傳播級別屬性設置不當

場景描述:在Spring的事務管理中,如果在一個支持當前事務的方法(比如,已經被標記為@Transactional的方法)中調用了一個需要新事務的方法,如果后者方法拋出了異常,但異常并未被Spring識別為需要回滾事務的異常,那么后者的事務將不會回滾。

異常類型不匹配

場景描述:默認情況下,Spring只有在方法拋出運行時異常或者錯誤時才會回滾事務。對于檢查性異常,即使你在方法中拋出了,Spring也不會回滾事務,除非你在@Transactional注解中顯式地指定需要回滾哪些檢查性異常。

解決方案:了解Spring事務管理對異常的處理,必要時在@Transactional注解中指定需要回滾的異常類型。

事務攔截器配置錯誤

場景描述:如果沒有正確地配置事務攔截器,例如沒有指定切入點或指定了錯誤的切入點,就會導致Spring事務失效。

@EnableTransactionManagement
@Configuration
public class TxConfig {@Beanpublic Advisor transactionAdvisor() {AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();pointcut.setExpression("execution(* com..service.*.*(..))"); // 包路徑錯誤return new DefaultPointcutAdvisor(pointcut, transactionInterceptor());}
}

事務超時配置錯誤

場景描述:如果事務超時時間設置得太短,就有可能在事務執行過程中出現超時,從而導致Spring事務失效。

Spring事務超時是通過JDBC的java.sql.Connection#setNetworkTimeout()實現的,底層流程:

if (System.currentTimeMillis() - startTime > timeoutMillis) {throw new TransactionTimedOutException("Transaction timed out");
}

Spring事務失效場景深度解析

一、非public方法失效的本質原因

底層機制

  1. 代理生成限制
// Spring源碼中的判斷邏輯
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {return null; // 直接返回不創建事務屬性
}
    • JDK動態代理只能代理接口中的public方法
    • CGLIB雖然能代理類方法,但Spring主動限制了非public方法的事務支持
  1. 設計考量
    • 非public方法通常被視為內部實現細節
    • 保持事務邊界清晰(public方法才是服務契約)

典型錯誤示例

@Service
public class PaymentService {@Transactionalprotected void processPayment() {  // protected方法// 事務不會生效!}
}

二、同類調用失效的代理機制

核心問題圖解

[客戶端] --> [Spring代理對象] --> [真實對象]調用createOrder()       this.validate()繞過代理

字節碼層面分析

  1. 代理對象生成后,方法調用流程:
    • 外部調用:proxy.createOrder()
    • 內部調用:realObject.validate()(直接調用,不走代理)

解決方案對比

方案

優點

缺點

拆分類

符合單一職責原則

增加類數量

自注入

改動最小

存在循環依賴風險

AopContext.currentProxy()

靈活

需配置exposeProxy=true

三、傳播行為配置陷阱

REQUIRES_NEW的隔離性

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void auditLog() {// 即使外層事務回滾,此操作仍會提交// 但會創建新連接,可能耗盡連接池
}

NESTED的數據庫支持

  • 支持:MySQL、PostgreSQL
  • 部分支持:Oracle(行為差異)
  • 不支持:MyISAM引擎

四、異常處理不當的判定邏輯

Spring回滾決策樹

  1. 檢查rollbackFor/noRollbackFor明確指定的異常
  2. 默認規則:
    • RuntimeException及其子類 → 回滾
    • Error及其子類 → 回滾
    • 檢查型異常(Exception) → 提交

易錯場景示例

@Transactional
public void importData() throws IOException {try {parseFile(); // 可能拋出IOException} catch (IOException e) {throw new BusinessException(e); // 必須轉換為RuntimeException}
}

五、數據庫引擎關鍵影響

事務支持矩陣

引擎特性

InnoDB

MyISAM

Memory

事務支持

??

??

??

行級鎖

??

??

??

外鍵支持

??

??

??

檢查方法

SHOW TABLE STATUS WHERE Name='table_name';

六、靜態/最終方法限制

JVM方法調用機制

  • final方法:靜態綁定,編譯期確定調用目標
  • static方法:類級別調用,與對象實例無關
  • 二者都無法被動態代理攔截

事務調試四步法

  1. 檢查代理類型
System.out.println(service.getClass().getName());
// 應輸出包含$$EnhancerBySpringCGLIB$$或$Proxy的類名
  1. 驗證事務狀態
TransactionSynchronizationManager.isActualTransactionActive();
TransactionSynchronizationManager.getCurrentTransactionName();
  1. 開啟事務日志
logging.level.org.springframework.transaction.interceptor=TRACE
logging.level.org.springframework.jdbc=DEBUG
  1. 數據庫監控
SHOW ENGINE INNODB STATUS;  -- MySQL
SELECT * FROM V$TRANSACTION; -- Oracle

最佳實踐清單

  1. 編碼規范
    • 所有事務方法必須為public
    • 避免在事務方法中捕獲所有異常
    • 顯式指定rollbackFor
  1. 配置檢查
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
public class TxConfig {@Beanpublic PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(dataSource());}
}
  1. 測試驗證
@Test
@Transactional
public void testWithRollback() {// 測試后自動回滾assertThrows(Exception.class, () -> service.method());
}

理解這些原理后,可以系統性地避免事務失效問題,而不僅是記住表面現象。實際開發中建議結合日志監控和單元測試,確保事務行為符合預期。

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

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

相關文章

1.電動汽車動力電池系統技術介紹與分類

1.電動汽車動力電池系統技術介紹與分類 1.1 電動汽車發展的三個 “黃金時代” 第一個黃金時代(19 世紀末 - 20 世紀初) 技術基礎:鉛酸蓄電池發明(1859 年),推動電動三輪車(1873 年)、…

調用阿里云-阿里云百煉 AI

相關文檔:大模型服務平臺百煉控制臺 多輪對話:通義千問模型的多輪對話_大模型服務平臺百煉(Model Studio)-阿里云幫助中心 創建知識庫:大模型服務平臺百煉控制臺 創建智能體:大模型服務平臺百煉控制臺 點擊智能體發布后&#x…

Apache Flink:從實時數據分析到實時AI

引言歡迎踏上這段深入了解 Apache Flink 演進歷程的旅程,Apache Flink 是一項重新定義了實時數據處理的技術。本博客文章基于王峰(阿里云開放數據平臺負責人、Apache Flink Committer)在 2025 年 Flink Forward Asia 新加坡大會上的演講內容編…

oelove奧壹新版v11.7旗艦版婚戀系統微信原生小程序源碼上架容易遇到的幾個坑,避免遺漏參數白屏顯示等問題

oelove和 金媒我都用過一段時間,其中oelove 用的時間較多,也比較了解這個系統,這個系統比較不錯的就是小程序是原生的(完全遵循微信開發者平臺規則非Uniapp)開發的,原生小程序的特點就是兼容性好&#xff0…

行為模式-模板方法模式

定義:Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithms structure.(定義一個操作中的算法的框架&a…

Java集合遍歷練習題

以下是10道難度遞增的集合遍歷練習題,涵蓋List、Set、Map的各種遍歷方式,包含解題思路、代碼實現和輸出結果: 練習題1:基礎遍歷 - ArrayList的for-each遍歷 題目:創建一個存儲5個字符串的ArrayList(元素為&…

深度學習·ZegclipClip-RC

Zegclip 獲取圖像的特殊編碼:使用prompt tuning的技術,目的是減少過擬合和計算量。調整文本編碼:使用RD關系描述符,將每一個文本對應的[cls] token和圖像對應的[cls] token作哈密頓積,最后文本[cls]token形式化任務 文…

Taro 擴展 API 深度解析與實戰指南

Taro 擴展 API 深度解析與實戰指南 Taro 作為一款優秀的多端開發框架,提供了一系列強大的擴展 API,這些 API 極大地提升了開發效率和應用的可維護性。本文將深入解析 Taro 的擴展 API,并根據其功能特性進行分類講解,幫助開發者更…

容器之王--Docker的部署及基本操作演練

1.2 部署docker 1.2.1 容器工作方法1.2.2 部署第一個容器 官方站點:https://docs.docker.com/ 1.2.2.1 配置軟件倉庫 ]# cd /etc/yum.repos.d ]# vim docker.repo [docker] name docker-ce baseurl https://mirrors.aliyun.com/docker-ce/linux/rhel/9/x86_64/sta…

VFTO與局部放電-高壓設備絕緣系統的雙重挑戰與防護策略

目錄 引言VFTO的定義與形成機理VFTO對高壓設備絕緣系統的影響局部放電的危害與機制VFTO與局部放電的關聯性分析檢測與監測技術防護與抑制措施未來技術發展趨勢結論與展望引言 在現代電力系統中,超快速暫態過電壓(Very Fast Transient Overvoltage, VFTO&…

Windows下Rust編碼實現MP4點播服務器

Rust編碼可以實現眾多簡潔、可靠、高效的應用,但語法邏輯要求嚴格,尤其是依賴庫的選擇調用,需要耐心堅持“推敲”。借助DeepSeek并反復編程調試和問答改進,可以最終得到完整有效的Rust編碼。下面分享Windows下Rust編碼實現MP4點播…

ubuntu-相關指令

1、串口1.1確認在系統中檢查設備是否正常加載,在終端輸入以下命令:way1:ll /dev | grep ttyUSB(ll是LL的小寫) way2:ll /dev | grep ttyACM way3:ll /dev | grep ttyCH343USB&#…

docker容器臨時文件去除,服務器容量空間

概述: 接到告警提醒,服務器容量不足,去查看了一下,發現確實100g左右容量已基本用完;分析: 1)查看根目錄下哪些文件夾占用容量較大 使用命令“ du -ah --max-depth1 / ” 查看目標目錄下所有文件…

損耗對信號質量的影響

損耗通常分為介質損耗與導體損耗:介質損耗:介質被施加電場后介質內部帶電粒子在外加電場的作用力下進行微小移動介質損耗與頻率成正比導體損耗:導體由于存在電阻,在有電流流過時產生的熱量造成的損耗為導體損耗。同時,…

【42】【OpenCV C++】 計算圖像某一列像素方差 或 某一行像素的方差;

文章目錄1 要使用到的函數 和 原理1.1 cv::meanStdDev 函數詳解——計算均值和標準差1 .2 方差的通俗解釋2 代碼實現3 問題3.1 入口參數const cv::Mat& img 和 const cv::Mat img區別項目要求:C OPenCV 中 圖像img ,當 string ROIdirection “H”時,…

元圖 CAD 插件化革命:突破效率瓶頸,重構智能協作新范式

在建筑、機械、機電等工程領域,傳統CAD軟件的功能固化與場景割裂已成為效率提升的瓶頸。設計師常面臨“通用工具難適配專業需求”、“跨平臺協作效率低下”、“數據孤島阻礙創新”等痛點。元圖CAD憑借“場景插件化“核心技術,以模塊化能力突破行業桎梏&a…

T:歸并排序

歸并排序.逆序對簡介.歸并排序.習題.逆序對簡介 \;\;\;\;\;\;\;\;簡單介紹一下歸并排序的原理&#xff0c;逆序對的基本概念&#xff0c;然后收集相關的練習。 直接用一個基礎問題來引入。 因此知道了: \;\;\;\;\;\;\;\;逆序對就是一對數滿足 i<j&&nums[i]>nu…

三極管三種基本放大電路:共射、共集、共基放大電路

文章目錄一、共集放大電路1.靜態分析2.動態分析二、共基放大電路1.靜態分析2.動態分析總結如何判斷共射、共集、共基放大電路&#xff1f; 電路的輸入回路與輸出回路以發射極為公共端的電路稱為共射放大電路。 電路的輸入回路與輸出回路以集電極為公共端的電路稱為共集放大電路…

Function AI 助力用戶自主開發 MCP 服務,一鍵上云高效部署

作者&#xff1a;靖蘇 在 AI 與云原生協同創新的浪潮下&#xff0c;多模型、多場景智能應用日益普及。開發者面臨的首要挑戰&#xff0c;是如何實現模型之間、服務之間的高效協同&#xff0c;以及如何便捷地將自主研發能力拓展到云端&#xff0c;形成靈活可擴展的智能服務。MC…

c++編譯環境安裝(gcc、cmake)

一、gcc下載 下載地址&#xff1a;https://ftp.gnu.org/gnu/gcc/ 選擇想要下載的版本&#xff0c;然后解壓&#xff0c;查看 contrib/download_prerequisites 中的依賴。 以我下載的 gcc-7.3.0 為例&#xff0c; 二、安裝依賴包 【gmp】 https://ftp.gnu.org/gnu/gmp/ 【is…