SpringBoot的测试类中使用@Transactional注解
前言 先讲一个很多人踩过的坑:数据库里有一列数据需要根据条件update成不同状态,写了个测试用例,直接从 ServiceImpl 里复制了一个方法到 Test 里,改了几行代码就执行了。控制台打印出来的 update 语句看起来很正常,但查数据库——纹丝不动。排查了半天才反应过来:被复制的方法上带
前言
先讲一个很多人踩过的坑:数据库里有一列数据需要根据条件update成不同状态,写了个测试用例,直接从 ServiceImpl 里复制了一个方法到 Test 里,改了几行代码就执行了。控制台打印出来的 update 语句看起来很正常,但查数据库——纹丝不动。排查了半天才反应过来:被复制的方法上带了 @Transactional 注解,而测试方法上只加了个 @Test,事务自动回滚了,相当于白忙一场。

这类问题其实很常见,但根源在于对 Spring Boot 测试中 @Transactional 的行为理解得不够透彻。今天就把这块知识彻底捋一遍。
1. 默认行为:事务回滚
在 Spring Boot 的测试类(或测试方法)上加上 @Transactional 时,默认的行为是:整个测试方法运行在一个事务中,而且测试结束后,事务会自动回滚——不会提交。
后果很明确:
- 测试中执行的修改 SQL(比如
UPDATE user SET name = 'test' WHERE id = 1)在事务内部是生效的。 - 同一事务内的其他操作(比如查询)能看到这些修改。
- 但一旦测试方法执行完毕,Spring 二话不说就把事务回滚了,所有对数据库的改变都不会保留下来。
2. 为什么这样设计?
这么设计不是坑人,而是为了确保测试的独立性和可重复性:
- 每个测试跑完之后,数据库状态恢复原样,不会影响后面的测试。
- 测试之间不会产生副作用,跑一万次结果都一样。
- 你也不用在后置方法里手动清理数据,省了不少事。
说白了,就是让测试可以安心地“造脏数据”,用完就扔,谁都不欠谁。
3. 示例代码
@SpringBootTest
@Transactional
class UserServiceTest {
@Autowired
private UserService userService;
@Autowired
private UserRepository userRepository;
@Test
void testUpdateUser() {
// 查询原始数据
User user = userRepository.findById(1L).orElseThrow();
String originalName = user.getName();
// 执行修改 SQL(通过 Service 或直接 JPA)
userService.updateUserName(1L, "NewName");
// 在当前事务中可以查到修改
User updatedUser = userRepository.findById(1L).orElseThrow();
assertEquals("NewName", updatedUser.getName());
// 测试结束,@Transactional 会导致事务回滚
// 数据库中 id=1 的用户姓名仍为 originalName
}
}
这个例子很清楚地展示了:updateUserName 执行的修改在测试方法内部是可见的,但测试一结束,数据库实际数据纹丝未变。
4. 如何让修改真正提交?
有些场景下(比如集成测试、性能测试),你确实希望修改真的写进数据库。那该怎么办?两种常用方式:
方法一:移除 @Transactional
@SpringBootTest
// 不加 @Transactional,每次修改都会提交
class IntegrationTest {
@Test
void testPersistData() {
// 修改会真正写入数据库
}
}
直接去掉类级别或方法级别的 @Transactional,事务就不会自动回滚了——前提是你确认自己的操作没有包裹在其他事务中。
方法二:使用 @Commit 注解
@SpringBootTest
@Transactional
class UserServiceTest {
@Test
@Commit // 明确告诉 Spring 提交事务,而不是回滚
void testUpdateAndCommit() {
userService.updateUserName(1L, "CommittedName");
// 测试结束后,修改会真正写入数据库
}
}
@Commit 是 Spring 测试框架提供的“反悔药”,在 @Transactional 基础上临时改变行为:只针对这一个测试方法提交事务,其他方法依然回滚。这样既保持了大多数测试的独立性,又能对个别需求灵活处理。
Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。
极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。
















