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

Spring Boot 2事务测试执行完成后无法回滚问题

解决Spring Boot 2 + JUnit4测试中JDBCTemplate插入数据不回滚的问题

我之前也碰到过一模一样的坑,折腾了好一会儿才捋清楚原因,结合你的场景咱们一步步排查:

1. 先确认测试类的核心注解是否齐全

JUnit4下Spring测试的事务注解要生效,必须让Spring容器接管测试类,你得确保测试类上有这两个关键注解:

  • @RunWith(SpringRunner.class)(或者SpringJUnit4ClassRunner.class,两者是别名):告诉JUnit用Spring的测试运行器执行测试
  • @SpringBootTest(或者@ContextConfiguration指定你的配置类):加载Spring Boot的应用上下文

要是缺了这俩,@Transactional和@Rollback根本不会被Spring识别,自然不会触发回滚。

2. 检查MySQL表的存储引擎

MySQL的MyISAM引擎完全不支持事务!如果你的customers表用的是MyISAM,哪怕加了再多事务注解也白搭。你可以执行这条SQL查看表引擎:

SHOW CREATE TABLE customers;

如果输出里显示Engine=MyISAM,赶紧改成InnoDB:

ALTER TABLE customers ENGINE=InnoDB;

3. 确认注解的包路径正确

别把Spring的事务注解和JUnit的搞混了!你要导入的是:

  • org.springframework.transaction.annotation.Transactional(不是JUnit的org.junit.Transaction)
  • org.springframework.test.annotation.Rollback(不是JUnit的相关注解)

4. 排查测试代码里的手动提交操作

如果你的测试方法里手动调用了事务提交(比如transactionManager.commit()),或者加了@Commit注解,那@Rollback就会被覆盖,数据自然会保留下来。

完整的正确测试类示例

给你贴个符合要求的测试类模板,你可以对照调整:

import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.test.annotation.Rollback;
import org.springframework.boot.test.context.SpringBootTest;

@RunWith(SpringRunner.class)
@SpringBootTest
public class CustomerInsertTest {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    @Transactional
    @Rollback // 默认就是true,可省略
    public void testInsertCustomer() {
        // 执行插入
        String insertSql = "INSERT INTO customers(name, email) VALUES (?, ?)";
        jdbcTemplate.update(insertSql, "TestCustomer", "test@example.com");

        // 验证插入成功
        Integer count = jdbcTemplate.queryForObject(
            "SELECT COUNT(*) FROM customers WHERE name = ?", 
            Integer.class, 
            "TestCustomer"
        );
        assertEquals(1, count.intValue());
    }
}

按上面的步骤排查一遍,应该就能解决数据不回滚的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:01:57