SpringBoot事務(wù)失效的七種場景分析及解決方案
事務(wù)失效場景1:方法非public修飾
原因
Spring事務(wù)基于動態(tài)代理(AOP)實現(xiàn),非public方法無法被代理攔截,導(dǎo)致事務(wù)失效。
代碼示例
@Service
public class OrderService {
@Transactional
private void createOrder() { // 非public方法
// 業(yè)務(wù)邏輯
}
}
解決方案
- 將方法改為
public修飾。 - 若需限制方法訪問權(quán)限,可通過編程式事務(wù)(
TransactionTemplate)實現(xiàn)。
事務(wù)失效場景2:自調(diào)用問題
原因
同類中方法A調(diào)用方法B(帶@Transactional),由于代理機制失效,事務(wù)不生效。
代碼示例
@Service
public class UserService {
public void updateUser() {
this.saveUser(); // 自調(diào)用
}
@Transactional
public void saveUser() {
// 數(shù)據(jù)庫操作
}
}
解決方案
- 將事務(wù)方法拆分到另一個類中,通過注入調(diào)用。
- 使用
AopContext.currentProxy()獲取代理對象(需開啟exposeProxy)。
事務(wù)失效場景3:異常類型未被捕獲
原因
默認僅對RuntimeException和Error回滾,若拋出其他異常(如IOException)且未配置rollbackFor,事務(wù)不會回滾。
代碼示例
@Transactional
public void processData() throws IOException {
// 拋出IOException
throw new IOException("文件異常");
}
解決方案
- 明確指定回滾異常類型:
@Transactional(rollbackFor = Exception.class)
事務(wù)失效場景4:事務(wù)傳播行為配置錯誤
原因
例如REQUIRES_NEW嵌套使用時,內(nèi)層事務(wù)失敗可能不影響外層事務(wù)。
代碼示例
@Transactional(propagation = Propagation.REQUIRED)
public void outerMethod() {
innerMethod(); // 內(nèi)層事務(wù)獨立提交
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void innerMethod() {
// 操作失敗但outerMethod繼續(xù)執(zhí)行
}
解決方案
- 根據(jù)業(yè)務(wù)需求調(diào)整傳播行為,如改為
REQUIRED。 - 避免過度嵌套事務(wù)。
事務(wù)失效場景5:多數(shù)據(jù)源未指定事務(wù)管理器
原因
多數(shù)據(jù)源環(huán)境下未明確指定transactionManager,導(dǎo)致事務(wù)綁定到默認管理器。
代碼示例
@Transactional // 默認使用primary事務(wù)管理器
public void saveToSecondaryDB() {
// 操作secondary數(shù)據(jù)源
}
解決方案
- 注解中指定事務(wù)管理器:
@Transactional("secondaryTransactionManager")
事務(wù)失效場景6:手動捕獲異常未拋出
原因
捕獲異常后未重新拋出,事務(wù)攔截器無法觸發(fā)回滾。
代碼示例
@Transactional
public void updateOrder() {
try {
// 數(shù)據(jù)庫操作
} catch (Exception e) {
log.error("錯誤", e); // 未拋出異常
}
}
解決方案
- 在
catch塊中拋出RuntimeException。 - 或使用
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()手動回滾。
事務(wù)失效場景7:非事務(wù)方法調(diào)用事務(wù)方法
原因
若父類方法未開啟事務(wù),調(diào)用子類@Transactional方法時,代理失效。
代碼示例
public class BaseService {
public void execute() {
save(); // 事務(wù)失效
}
@Transactional
public void save() {}
}
解決方案
- 將事務(wù)注解添加到父類方法。
- 避免通過繼承層級調(diào)用事務(wù)方法。
總結(jié)
- 檢查方法修飾符和代理機制。
- 確保異常類型和傳播行為匹配業(yè)務(wù)需求。
- 多數(shù)據(jù)源需顯式指定事務(wù)管理器。
- 優(yōu)先通過設(shè)計規(guī)避自調(diào)用問題。
以上就是SpringBoot事務(wù)失效的七種場景分析及解決方案的詳細內(nèi)容,更多關(guān)于SpringBoot事務(wù)失效場景的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot3整合Quartz實現(xiàn)定時任務(wù)的示例
Quartz 是一個開源的任務(wù)調(diào)度框架,用于在應(yīng)用程序中創(chuàng)建、管理和調(diào)度定時任務(wù),將 Quartz 和 Spring Boot 3 結(jié)合,可以輕松實現(xiàn)定時任務(wù)的靈活管理,本文將詳細介紹如何在 Spring Boot 3 項目中集成 Quartz Scheduler 并實現(xiàn)示例任務(wù)的調(diào)度,需要的朋友可以參考下2024-11-11
Windows下后端如何啟動SpringBoot的Jar項目
這篇文章主要介紹了Windows下后端如何啟動SpringBoot的Jar項目問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
springcloud?gateway實現(xiàn)簡易版灰度路由步驟詳解
這篇文章主要為大家介紹了springcloud?gateway實現(xiàn)簡易版灰度路由步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11
java導(dǎo)出數(shù)據(jù)庫中Excel表格數(shù)據(jù)的方法
這篇文章主要為大家詳細介紹了java導(dǎo)出數(shù)據(jù)庫中Excel表格數(shù)據(jù)的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08
java底層JDK?Logging日志模塊處理細節(jié)深入分析
這篇文章主要為大家介紹了java底層JDK?Logging日志模塊處理細節(jié)深入分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-03-03
使用SpringBoot實現(xiàn)自動發(fā)送注冊驗證碼郵件功能
一直以來,我都對程序如何自動發(fā)送郵件感到好奇,想象一下,當你在某個網(wǎng)站注冊時,輸入郵箱后不久就收到一封帶有驗證碼的郵件,這種體驗既方便又高效,所以本文給大家介紹了如何用?Spring?Boot?實現(xiàn)自動發(fā)送注冊驗證碼郵件,需要的朋友可以參考下2025-04-04

