Java事务回滚详解
一、什么是事务回滚?
事务回滚指的是:当执行过程中发生异常时,之前对数据库所做的更改全部撤销,数据库状态恢复到事务开始前的状态。这是数据库“原子性”原则的体现。
二、Spring 中的 @Transactional
默认行为
在 Spring 中,使用注解方式开启事务非常简单:
@Transactional
public void doSomething() {// 执行数据库操作
}
此时的默认行为是:
- 事务会在方法成功执行后提交;
- 遇到
RuntimeException
或Error
,会自动回滚; - 遇到
Checked Exception
(即编译时异常),不会自动回滚。
例如:
@Transactional
public void test1() {throw new RuntimeException(); // ✅ 会回滚
}@Transactional
public void test2() throws Exception {throw new Exception(); // ❌ 不会回滚
}
三、使用 rollbackFor
让事务回滚受检异常
如果你希望事务在任何异常发生时都回滚,包括受检异常,比如 IOException
、SQLException
,就需要显式指定:
@Transactional(rollbackFor = Exception.class)
public void test3() throws Exception {throw new Exception(); // ✅ 会回滚
}
rollbackFor
的值可以是一个或多个异常类;- 你可以根据需要选择只对某些异常类型回滚,其他的则不回滚。
四、rollbackFor
和 rollbackOn
的区别
特性 | rollbackFor | rollbackOn |
---|---|---|
适用范围 | Spring | Java EE / JTA |
包名 | org.springframework.transaction.annotation.Transactional | javax.transaction.Transactional |
默认行为 | 回滚RuntimeException | 不回滚任何异常 |
明确配置后 | 可回滚任何指定异常 | 可回滚任何指定异常 |
示例比较:
Spring 中的写法:
import org.springframework.transaction.annotation.Transactional;@Transactional(rollbackFor = Exception.class)
public void springTransaction() throws Exception {throw new Exception("测试受检异常");
}
JTA(Java EE)中的写法:
import javax.transaction.Transactional;@Transactional(rollbackOn = Exception.class)
public void jtaTransaction() throws Exception {throw new Exception("测试受检异常");
}
注意:使用的是不同的注解类,不能混用!
五、常见误区
❌ 误区1:以为所有异常都会触发事务回滚
Spring 默认只回滚 RuntimeException
,不会回滚 Exception
(受检异常)。这是导致事务未回滚的最常见原因。
❌ 误区2:以为 @Transactional
可以应用于任何方法
只有被 Spring 容器管理(即被 Spring 扫描并代理)的类中的 public
方法,@Transactional
才有效。如果你在 private
方法上加了注解,是不会生效的。
❌ 误区3:使用错误的注解类
Spring 和 JTA 的 @Transactional
注解来自不同的包,使用时务必导入正确:
- Spring:
org.springframework.transaction.annotation.Transactional
- JTA:
javax.transaction.Transactional
六、小结
常见问题与解决方式
问题 | 默认行为 | 解决方式 |
---|---|---|
事务不回滚受检异常 | ❌ 不回滚 | ✅ 添加rollbackFor = Exception.class (Spring)或 rollbackOn = Exception.class (JTA) |
事务注解不生效 | ❌ 方法不是public ,类未被 Spring 管理 | ✅ 保证类被 Spring 扫描,方法为public |
导入错误注解 | ❌ 使用了错误的@Transactional 注解 | ✅ 使用正确包名下的注解(见下表) |
Spring 与 JTA 的 @Transactional
对比
特性 | Spring | JTA(Java EE) |
---|---|---|
注解类全名 | org.springframework.transaction.annotation.Transactional | javax.transaction.Transactional |
默认回滚行为 | 回滚RuntimeException ,不回滚 Exception | 不回滚任何异常 |
控制参数 | rollbackFor , noRollbackFor 等 | rollbackOn , dontRollbackOn |
常见场景 | Spring Boot, Spring MVC 项目 | Java EE, Jakarta EE 应用服务器项目 |
建议用法 | 用 Spring 的事务注解为主 | 仅在 Java EE 项目中使用 |
七、结语
事务控制是保障系统数据一致性的重要手段,理解事务的回滚机制尤为重要。在实际开发中,推荐明确指定异常回滚策略,避免因受检异常不回滚而造成数据异常。
希望这篇文章能帮你在开发中更精准地使用 @Transactional
,写出更健壮、可控的代码。如果你有更多问题,欢迎留言讨论!