Java?Spring聲明式事務(wù)失效情況解決辦法(天翼通訊)
事務(wù)失效排查清單
當(dāng)事務(wù)不生效時,檢查這個清單:
? 方法是否是public?
? 異常是否被正確拋出?
? 是否配置了正確的rollbackFor?
? 是否是內(nèi)部調(diào)用?
? 傳播行為設(shè)置是否正確?
? 是否配置了事務(wù)管理器?
? 數(shù)據(jù)源是否支持事務(wù)?
Spring事務(wù)默認(rèn)只回滾RuntimeException和Error。
想象Spring事務(wù)管理就像一個馬戲團導(dǎo)演,@Transactional注解就是他的指揮棒。但有時候,演員們不按導(dǎo)演的指揮來表演!
失效場景1:內(nèi)部方法調(diào)用 - "導(dǎo)演被架空"
@Service
public class CircusService {
public void bigShow() {
System.out.println("開始大表演...");
// 問題:在同一個類內(nèi)部調(diào)用事務(wù)方法
fireDance(); // 事務(wù)失效!
// 相當(dāng)于:導(dǎo)演喊"開始",但演員自己演自己的
}
@Transactional
public void fireDance() {
System.out.println("火焰舞蹈開始...");
// 數(shù)據(jù)庫操作...
if (Math.random() > 0.5) {
throw new RuntimeException("火焰太大!");
}
// 即使拋異常,事務(wù)也不會回滾!
}
}為什么會失效?
Spring事務(wù)基于AOP代理
內(nèi)部調(diào)用繞過了代理對象
就像導(dǎo)演在外面喊,但演員在帳篷里聽不見
失效場景2:異常類型不對 - "導(dǎo)演認(rèn)錯信號"
@Service
public class CircusService {
@Transactional
public void tightropeWalking() throws Exception {
System.out.println("走鋼絲表演...");
// 數(shù)據(jù)庫操作...
// 問題:拋出了檢查異常,但Spring默認(rèn)只回滾運行時異常
if (balanceTooLow()) {
throw new Exception("平衡感不好!"); // 事務(wù)不回滾!
}
// 只有RuntimeException才會觸發(fā)回滾
throw new RuntimeException("摔下來了!"); // 這個會回滾
}
}失效場景3:異常被吃掉 - "導(dǎo)演沒看到事故"
@Service
public class CircusService {
@Transactional
public void lionTaming() {
try {
System.out.println("馴獅表演...");
// 數(shù)據(jù)庫操作...
throw new RuntimeException("獅子發(fā)怒了!");
} catch (Exception e) {
System.out.println("悄悄處理異常,導(dǎo)演沒看見...");
// 異常被捕獲,事務(wù)不知道要回滾!
}
}
}失效場景4:非public方法 - "導(dǎo)演管不了后臺"
@Service
public class CircusService {
@Transactional
private void backstagePreparation() { // 私有方法!
System.out.println("后臺準(zhǔn)備工作...");
// 事務(wù)失效!Spring代理無法攔截私有方法
}
@Transactional
protected void equipmentCheck() { // protected方法!
// 同樣可能失效,取決于代理方式
}
}失效場景5:錯誤的傳播機制 - "導(dǎo)演指揮混亂"
@Service
public class CircusService {
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void clownPerformance() {
System.out.println("小丑表演...");
// 這個方法根本不在事務(wù)中運行!
acrobatics(); // 即使調(diào)用的事務(wù)方法,也不會加入事務(wù)
}
@Transactional
public void acrobatics() {
// 因為外層沒有事務(wù),這里會開啟新事務(wù)
}
}失效場景6:多數(shù)據(jù)源配置問題 - "多個導(dǎo)演搶指揮"
@Service
public class CircusService {
// 如果配置了多個事務(wù)管理器,需要指定用哪個
@Transactional // 不指定的話,Spring不知道用哪個TransactionManager
public void multiRingShow() {
// 操作多個數(shù)據(jù)源...
}
}解決方案:
@Transactional("firstTransactionManager") // 明確指定事務(wù)管理器
public void mainRingShow() {
// 使用第一個數(shù)據(jù)源的事務(wù)
}
?
@Transactional("secondTransactionManager")
public void secondRingShow() {
// 使用第二個數(shù)據(jù)源的事務(wù)
}總結(jié)
內(nèi)部調(diào)用 = 導(dǎo)演在外面喊,演員在帳篷里聽不見
異常類型不對 = 導(dǎo)演只認(rèn)RuntimeException這種"緊急信號
異常被吃掉 = 事故發(fā)生了,但沒人告訴導(dǎo)演
非public方法 = 導(dǎo)演管不了后臺私事
錯誤傳播機制 = 導(dǎo)演指揮混亂
多數(shù)據(jù)源配置問題 = 多個導(dǎo)演搶指揮
記?。篠pring事務(wù)就像馬戲團導(dǎo)演,必須讓他在正確的時間、正確的地點、看到正確的事情,才能有效管理整個表演!
到此這篇關(guān)于Java Spring聲明式事務(wù)失效情況解決辦法的文章就介紹到這了,更多相關(guān)Java Spring聲明式事務(wù)失效內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談java中Math.random()與java.util.random()的區(qū)別
下面小編就為大家?guī)硪黄獪\談java中Math.random()與java.util.random()的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09
java實現(xiàn)兩張圖片2D翻轉(zhuǎn)動畫效果
這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)兩張圖片2D翻轉(zhuǎn)動畫效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-08-08
SpringBoot+Vue+Flowable模擬實現(xiàn)請假審批流程
這篇文章主要為大家詳細(xì)介紹了如何利用SpringBoot+Vue+Flowable模擬實現(xiàn)一個請假審批流程,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-08-08
Mybatis-plus更新字段為null兩種常用方法及優(yōu)化
Mybatis Plus在進行更新操作時,默認(rèn)情況下是不能將字段更新為null的,如果要更新字段為null,需要進行以下處理,這篇文章主要給大家介紹了關(guān)于Mybatis-plus更新字段為null的兩種常用方法及優(yōu)化,需要的朋友可以參考下2024-03-03
Spring配置多個數(shù)據(jù)源并實現(xiàn)動態(tài)切換示例
本篇文章主要介紹了Spring配置多個數(shù)據(jù)源并實現(xiàn)動態(tài)切換示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04

