spring事务默认仅对runtimeexception及其子类和error自动回滚,对ioexception等受检异常不回滚;可通过rollbackfor指定受检异常回滚,norollbackfor排除特定异常不回滚;内部吞异常、异步调用、代理失效等场景会导致回滚失败。

Spring 事务默认只对 非受检异常(RuntimeException 及其子类)和 Error 自动回滚,而对 受检异常(Exception 及其子类,但不包括 RuntimeException)默认不回滚。
默认行为:哪些异常触发回滚?
Spring 的 @Transactional 注解基于 AOP 实现,默认使用 TransactionInterceptor 判断是否回滚。它的回滚策略由 RollbackRuleAttribute 控制,初始规则是:
- 遇到
RuntimeException或其任意子类 → 回滚 - 遇到
Error→ 回滚 - 遇到普通
Exception(如IOException、SQLException)→ 不回滚(事务正常提交)
如何让受检异常也触发回滚?
通过 @Transactional 的 rollbackFor 属性显式指定:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
@Transactional(rollbackFor = Exception.class):所有异常都回滚(含受检异常) -
@Transactional(rollbackFor = {IOException.class, SQLException.class}):只对列出的受检异常回滚 - 注意:
rollbackFor接收Class extends Throwable>数组,支持多类型
如何阻止非受检异常回滚?
用 noRollbackFor 属性排除特定异常(即使它是 RuntimeException):
-
@Transactional(noRollbackFor = IllegalArgumentException.class):该异常发生时不回滚 -
@Transactional(rollbackFor = Exception.class, noRollbackFor = BusinessException.class):全局回滚,但业务异常除外
关键细节与常见误区
以下情况事务不会按预期回滚,需特别注意:
- 异常被方法内部吞掉:try-catch 后未重新抛出,事务切面捕获不到异常 → 不回滚
- 抛出的异常不在当前事务方法调用链上:异步调用、新线程、手动 new Thread() 中的异常不影响外层事务
- 代理失效场景:同一类中非 public 方法调用、this. 调用事务方法 → AOP 代理未生效 → @Transactional 失效
- checked exception 继承自 RuntimeException:它就变成非受检异常,自动回滚(无需 rollbackFor)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










