Java事务回滚测试需用@Transactional+@Rollback自动回滚,抛RuntimeException触发回滚并查库断言验证;注意异常类型、public方法、避免自调用等陷阱。

测试 Java 中带有事务的方法是否能正确回滚,核心是模拟异常触发事务回滚,并验证数据库状态未被修改。关键在于使用 Spring 的测试支持(如 @Transactional 和 @Rollback),避免污染测试数据库,同时确保事务边界和异常传播行为符合预期。
用 @Transactional + @Rollback 自动回滚测试事务
Spring Test 默认在测试方法上加 @Transactional 时,会启动一个事务,并在方法结束时自动回滚(无需显式写 @Rollback(true),因为这是默认行为)。
- 确保测试类或方法标注了
@Transactional(来自org.springframework.transaction.annotation.Transactional) - 测试中调用被
@Transactional修饰的业务方法,该方法内部抛出未被捕获的运行时异常(如RuntimeException或其子类) - Spring 检测到异常后会触发事务回滚,测试结束后数据库保持原样
- 注意:若业务方法 catch 了异常且未重新 throw,事务不会回滚——这是常见疏漏
主动验证回滚效果:查库 + 断言
不能只依赖“没报错”就认为回滚成功,必须检查数据是否真的没写入。
- 在方法调用前记录关键数据(如主键最大值、某条记录的状态)
- 调用目标方法(让它抛异常)
- 捕获异常后,立即查询数据库,确认新增/修改/删除操作未生效
- 例如:
assertThat(jdbcTemplate.queryForObject("SELECT COUNT(*) FROM order", Integer.class)).isEqualTo(0);
测试不同异常类型对回滚的影响
Spring 默认只对 RuntimeException 和 Error 回滚,对受检异常(Exception 及子类)不回滚——除非显式配置。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 测试默认行为:抛
new RuntimeException("boom")→ 应回滚 - 测试受检异常:抛
new Exception("oops")→ 默认不回滚,需在方法上加@Transactional(rollbackFor = Exception.class)后再验证 - 可结合
@Test(expected = RuntimeException.class)或Assertions.assertThrows()确保异常抛出
避免事务失效的陷阱
事务不回滚,常常不是逻辑问题,而是事务未真正生效。
- 方法不是 public:Spring AOP 代理不生效,事务注解无效
- 自调用(this.method()):同一类内调用,绕过代理,事务失效
- 事务传播行为设为
NOT_SUPPORTED或NEVER:主动关闭事务 - 使用了错误的事务管理器(比如配置了多个
PlatformTransactionManager但没指定) - 测试类没启用 Spring 上下文(缺少
@SpringBootTest或@ContextConfiguration)
不复杂但容易忽略:事务测试成败,往往取决于是否真正进入了 Spring 代理方法、异常是否逃逸出事务边界、以及是否做了数据层面的最终验证。

















