☰
Spring 中事务失效的场景有哪些
2026/10/18 6:25:44 网站建设 项目流程

1、异常捕获处理,自己处理了异常,没有抛出

Spring 事务回滚是由TransactionInterceptor在捕获到业务方法向外抛出的异常后触发的。如果在业务里try-catch把异常吃掉了、没有重新抛出,拦截器就感知不到异常,会走 commit 分支导致事务失效。

以下是由于异常捕获处理导致的事务失效的场景与修复

try-catch 完全吞掉异常

try { doSomething(); } catch (Exception e) { log.error("转账失败", e); } // 拦截器看不到异常 → 提交

应该修复为:

@Transactional public void transfer(...) { try { doSomething(); } catch (Exception e) { log.error("转账失败", e); throw new BizException("转账失败", e); // 必须抛 } }

2、抛出检查异常

默认只回滚 RuntimeException(运行时异常,非受检异常),受检异常需要配置rollbackFor = Exception.class。

受检查异常默认不回滚

@Transactional // 默认只回滚 RuntimeException / Error public void doSomething() throws IOException { throw new IOException("IO错误"); // 受检异常,默认不回滚! }

应该修复为:

@Transactional(rollbackFor = Exception.class) // 显式指定 public void doSomething() throws IOException { throw new IOException("IO错误"); }

3、非 public 方法导致的事务失效

@Transactional只对public方法生效。如果标注在private、protected或包级(default)方法上,Spring 会静默忽略该注解——不报错,但方法完全没有事务能力。

失效案例:调用createOrder时:数据照插,异常照抛,但事务从未开启。

@Service public class OrderService { @Autowired private OrderMapper orderMapper; @Transactional private void createOrder(Order order) { // ❌ private → 事务不生效 orderMapper.insert(order); // 抛异常也不会回滚 throw new RuntimeException("测试"); } }

解决方案:直接把方法改为 public

@Transactional public void createOrder(Order order) { orderMapper.insert(order); }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询