Spring Boot事务默认仅对RuntimeException和Error回滚,检查异常如IOException不回滚;需用rollbackFor显式指定回滚异常,noRollbackFor排除特定异常不回滚,且@Transactional仅对public方法及外部调用生效。

Spring Boot 的事务管理默认开箱即用,核心是通过 @Transactional 注解实现声明式控制。回滚规则不是“写完就生效”的静态配置,而是由异常类型、注解属性和代理机制共同决定的。关键在于理解默认行为,并按需显式干预。
默认回滚行为:只对运行时异常和错误生效
Spring 不会因为抛出 IOException、SQLException 等检查型异常(checked exception)就自动回滚。它只在方法抛出未捕获的 RuntimeException 及其子类(如 NullPointerException、IllegalArgumentException)或 Error(如 OutOfMemoryError)时触发回滚。
- 抛出
new RuntimeException("fail")→ 自动回滚 - 抛出
new IOException()→ 默认不回滚,数据已提交 - 方法内
try-catch吞掉异常 → 事务不会感知异常,照样提交
用 rollbackFor 显式扩大回滚范围
当业务逻辑中必须抛出检查型异常,又希望它引发回滚时,必须用 rollbackFor 指定:
-
@Transactional(rollbackFor = Exception.class):让所有Exception及其子类都触发回滚 -
@Transactional(rollbackFor = {SQLException.class, IOException.class}):只对特定检查异常回滚 - 注意:
rollbackFor接收的是 Class 类型,不是异常实例
用 noRollbackFor 排除某些异常不回滚
有些异常属于预期中的业务提示(比如用户重复注册抛出 DuplicateKeyException),你希望保存操作继续生效,这时可排除:
立即学习“Java免费学习笔记(深入)”;
@Transactional(noRollbackFor = DuplicateKeyException.class)@Transactional(noRollbackFor = IllegalArgumentException.class)- 可同时使用
rollbackFor和noRollbackFor,后者优先级更高
事务代理限制:调用方式决定是否生效
@Transactional 依赖 Spring 的 AOP 代理,因此有重要约束:
- 只能加在 public 方法 上,private/protected 方法无效
- 必须由 外部 Bean 调用,同一类内 this.xxx() 调用会绕过代理,事务不生效
- 接口代理(JDK)或子类代理(CGLIB)均要求目标方法被代理对象调用,而非直接调用


















