You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成测试中事务回滚未生效问题排查

问题排查与解决方案

1. 测试类中dao变量未正确初始化

你的测试代码里private ThingDao dao;没有赋值,直接在断言中调用dao.getByName,导致你用的dao实例和事务中操作的TestDao不是同一个,查询结果自然无法反映事务回滚后的状态。

修复方式:在makeTestService中同时返回服务和DAO实例,确保查询用的是同一个操作过事务的DAO:

private @NotNull Pair<ThingService, ThingDao> makeTestService() {
    class TestDao extends ThingDao {
        public TestDao(final ThingMapper thingMapper) {
            super(thingMapper);
        }

        @Override
        public UUID createThing(final ThingModel model) {
            if (Objects.equals(model.name(), "Bad Request")) {
                throw new RuntimeException("Database exception");
            }
            return super.createThing(model);
        }
    }

    final ThingDao daoWithFailure = new TestDao(mapper);
    return Pair.of(new ThingService(daoWithFailure, txManager), daoWithFailure);
}

测试方法中调整为:

final Pair<ThingService, ThingDao> serviceAndDao = makeTestService();
final ThingService thingService = serviceAndDao.getFirst();
final ThingDao testDao = serviceAndDao.getSecond();

// ... 执行测试逻辑后
createRequests.forEach(req -> {
    assertTrue(testDao.getByName(req.name()).isEmpty()); 
});

2. @MybatisTest默认事务与手动事务冲突

@MybatisTest会自动给测试方法添加事务,默认测试结束后回滚。但你手动管理的事务会被外层测试事务包裹,你的回滚操作仅标记嵌套事务为回滚,外层事务最终可能提交,导致回滚效果失效。

解决方法:给测试方法添加注解禁用默认事务,让手动事务完全接管:

@Test
@Description("Should rollback on error")
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void rollbackOnError() throws MyBadRequestException {
    // ... 测试逻辑
}

3. 检查ThingDao的SqlSession自动提交配置

如果ThingDao的createThing方法使用的SqlSession开启了自动提交,每个插入操作会立即提交到数据库,不受你手动事务的控制。

确保ThingDao使用的是Spring管理的SqlSession(而非手动创建),测试中手动实例化的TestDao要依赖Spring注入的mapper,保证其操作绑定到当前事务上下文。

4. 显式设置事务传播行为

你用的DefaultTransactionDefinition默认传播行为是PROPAGATION_REQUIRED,如果存在外层事务会自动加入。可以强制开启新事务,避免受外层事务影响:

final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition();
txDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
final TransactionStatus txStatus = txManager.getTransaction(txDef);

内容的提问来源于stack exchange,提问作者Sydney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:22:46