@Transactional的rollbackFor接收Class<?>数组,支持任意异常类(如IOException.class、BusinessException.class),包括受检异常、非受检异常及Error子类,但不推荐指定Throwable.class以防覆盖默认Error回滚逻辑。

在 Java 的 Spring 框架中,@Transactional 默认只对 未检查异常(unchecked exception)(即继承自 RuntimeException 或 Error 的异常)自动回滚,而对 检查异常(checked exception)(如 IOException、SQLException 等)默认不回滚。若想让某些检查异常或特定的运行时异常也触发事务回滚,就需要通过 rollbackFor 属性显式指定。
rollbackFor 支持哪些类型的异常?
rollbackFor 接收一个 Class extends Throwable>[] 类型的数组,可以配置:
- 具体的异常类,如
IOException.class、MyBusinessException.class - 异常的父类(向上兼容),例如指定
Exception.class会让所有继承自Exception的异常都回滚 - 可同时配置多个异常类型,用逗号分隔
常见配置写法示例
以下是在方法上使用 @Transactional 并设置 rollbackFor 的典型方式:
@Transactional(rollbackFor = { IOException.class, SQLException.class })
public void transferMoney() throws IOException {
// 扣款、记账、发通知等操作
updateAccountBalance();
logTransaction();
sendNotification(); // 可能抛出 IOException
}
此时,只要该方法内抛出 IOException 或 SQLException(或其子类),当前事务就会回滚。
立即学习“Java免费学习笔记(深入)”;
注意 rollbackFor 和 noRollbackFor 的优先级关系
如果同时设置了 rollbackFor 和 noRollbackFor,Spring 会按如下逻辑判断:
- 先看抛出的异常是否匹配
noRollbackFor中的类型 —— 若匹配,则不回滚(即使它也在rollbackFor列表里) - 再看是否匹配
rollbackFor—— 若匹配且未被noRollbackFor排除,则回滚 - 都不匹配时,走默认规则(仅对
RuntimeException和Error回滚)
自定义业务异常建议这样用
为增强可读性和统一处理,推荐定义自己的运行时异常,并配合 rollbackFor 使用:
public class InsufficientBalanceException extends RuntimeException { ... }
@Transactional(rollbackFor = InsufficientBalanceException.class)
public void withdraw(Long accountId, BigDecimal amount) {
if (balance < amount) {
throw new InsufficientBalanceException("余额不足");
}
// 扣款逻辑...
}
这样既保持了代码语义清晰,又确保业务异常能准确触发回滚,无需强制声明 throws,也不依赖默认行为。
关键在于理解 Spring 的默认回滚策略是“保守”的,rollbackFor 是主动打开控制权的开关。配什么异常,就对什么异常负责回滚 —— 不配,就不回滚(除非是 RuntimeException 子类)。


















