spring事务rollbackfor支持指定任意异常类,包括受检异常(如ioexception、sqlexception)、自定义受检异常及exception.class等,但必须是class类型且异常需真实抛出至代理层。

Spring 事务默认只对 未检查异常(unchecked exception)(即继承自 RuntimeException 或 Error 的异常)自动回滚,而对检查异常(checked exception,如 Exception 及其子类,但不包括 RuntimeException)不会自动回滚。若想让事务在遇到特定检查异常时也回滚,就要用 rollbackFor 参数显式指定。
rollbackFor 支持哪些类型的异常
rollbackFor 接收一个 Class extends Throwable>[] 类型的数组,可以传入:
- 具体的异常类,如
IOException.class、SQLException.class - 异常的父类,如
Exception.class(此时所有继承自Exception的异常都会触发回滚) - 多个异常类,用逗号分隔,例如
@Transactional(rollbackFor = {IOException.class, CustomBizException.class})
常见写法示例
假设你有一个业务方法,调用外部 API 可能抛出 IOException,你希望此时事务也回滚:
@Transactional(rollbackFor = IOException.class)
public void updateUserAndNotify(User user) throws IOException {
userRepository.save(user);
notificationService.sendEmail(user.getEmail()); // 可能抛出 IOException
}
如果还想同时对自定义业务异常(比如 InsufficientBalanceException)回滚:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
@Transactional(rollbackFor = {IOException.class, InsufficientBalanceException.class})
public void transferMoney(...) throws IOException, InsufficientBalanceException {
// ...
}
注意 rollbackFor 和 noRollbackFor 的关系
两者可共存,noRollbackFor 优先级更高。例如:
@Transactional(
rollbackFor = Exception.class,
noRollbackFor = BusinessException.class
)
表示:除 BusinessException 外,所有 Exception 及其子类都回滚。即使 BusinessException 继承自 Exception,也不会触发回滚。
别忘了异常要真正“抛出”出去
@Transactional 是基于代理的 AOP 实现,只有从被代理方法内部抛出的异常才能被拦截并判断是否回滚。以下情况不会生效:
- 异常在方法内被
catch了且没重新抛出 - 异常从 private 方法或 this. 调用的方法中抛出(绕过代理)
- 使用了
try-catch-finally但没有throw或throw new RuntimeException(e)
务必确保异常最终传播到事务切面能捕获的位置。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










