在开发中Transactional可以说是最常用、也最容易踩坑的注解。明明加了注解结果异常不回滚、事务不生效数据错了还很难排查。今天这篇把Spring 事务失效 8 大高频场景一次性讲透每个场景都给你错误代码 正确代码线上真实踩坑总结建议收藏一、事务不生效先记住一句话Spring 事务是基于 AOP 代理实现的只有被 Spring 代理对象调用事务才会生效。凡是绕过代理的写法事务 100% 失效。二、8 大事务失效场景 解决方案1. 方法非 public最容易忽略错误java运行Service public class UserService { Transactional private void addUser() { // private → 事务失效 // 数据库操作 } }原因Spring 事务只对public 方法生效。正确java运行Transactional public void addUser() { }2. 内部调用本类方法最经典失效错误java运行Service public class OrderService { public void createOrder() { // 内部直接调用 → 不走代理 → 事务失效 doSave(); } Transactional public void doSave() { } }原因内部this.方法()不是代理对象调用。正确方案 1注入自身java运行Autowired private OrderService orderService; public void createOrder() { orderService.doSave(); }正确方案 2启用 AopContextjava运行((OrderService)AopContext.currentProxy()).doSave();3. 异常被 try-catch 吃掉了错误java运行Transactional public void update() { try { // 数据库操作 } catch (Exception e) { // 异常被吞 → 不回滚 } }正确要么不 catch要么 catch 后抛出java运行catch (Exception e) { throw new RuntimeException(e); }4. 抛出的异常不是 RuntimeException错误java运行Transactional public void test() throws Exception { throw new Exception(); // 默认不回滚 }原因Spring 默认只对RuntimeException / Error回滚。正确java运行Transactional(rollbackFor Exception.class)5. 类没有被 Spring 管理错误java运行// 没加 Service → 不受 Spring 管理 public class UserService { Transactional public void add(){} }正确java运行Service public class UserService6. 多线程调用极容易踩坑错误java运行Transactional public void test() { new Thread(() - { // 子线程里的数据库操作 // 不在同一个事务 → 不回滚 }).start(); }原因事务和线程绑定子线程不受主线程事务管理。解决子线程方法单独加 Transactional。7. 数据库引擎不支持事务错误MySQL 表引擎是MyISAM解决改成InnoDB。8. 传播机制配置错误错误java运行Transactional(propagation Propagation.NOT_SUPPORTED)事务不生效。常用正确java运行Transactional(propagation Propagation.REQUIRED)三、万能排查步骤记这 5 条方法是不是public是不是内部 this 调用异常有没有被 catch 吃掉是不是RuntimeException类有没有Service / Component按这个顺序查99% 的事务失效都能找到原因。四、总结超级好记Spring 事务失效只有一个核心没走代理、异常被吞、权限不对、配置错误。非 public → 失效内部调用 → 失效异常被吃 → 不回滚非运行时异常 → 不回滚多线程 / 新调用 → 独立事务你在项目中遇到过哪些奇葩事务失效评论区留言我来帮你定位