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

JUnit 5单元测试中数据库回滚失效问题求助

JUnit 5单元测试数据库回滚失效问题解决方案

核心原因

你代码里的回滚操作没生效,本质是添加成员的memberControl.addMember(member)使用了和当前测试代码不同的数据库连接。你手动创建的connect设置了autoCommit=false并执行回滚,但添加操作的连接不受这个设置影响,依然会自动提交数据到数据库。

解决方案

1. 统一数据库连接

修改memberControl的方法,让所有数据库操作复用同一个连接,确保事务覆盖所有测试步骤:

  • 调整addMember、viewMembers等方法,接收外部传入的Connection参数,不再内部创建新连接
  • 测试中所有数据库操作都使用同一个connect,确保回滚能覆盖添加操作

修改后的测试代码示例:

@Test 
public void TestAddMember() { 
    Member member = new Member();   
    try (Connection connect = BookControl_jdbc.connection()) {
        connect.setAutoCommit(false); // 禁用自动提交,开启事务
        try {
            // 填充成员数据(注意打开name的赋值,否则查询条件无效)
            String name = "lia";
            int age = 20;
            String gender = "F";
            String status = "ACTIVE";
            member.setName(name);
            member.setAge(age);
            member.setGender(gender);
            member.setStatus(status);

            // 传入统一连接执行添加和查询操作
            memberControl.addMember(connect, member);
            memberControl.viewMembers(connect);

            // 使用PreparedStatement避免SQL注入,同时确保用当前连接查询
            String singleMemberQuery = "SELECT Member_id,Member_name,Age,Gender, Member_Status FROM Member WHERE Member_name=?";
            try (PreparedStatement pstmt = connect.prepareStatement(singleMemberQuery)) {
                pstmt.setString(1, name);
                try (ResultSet rs = pstmt.executeQuery()) {
                    assertTrue(rs.next());
                    assertEquals(name, rs.getString("Member_name"));
                    assertEquals(age, rs.getInt("Age"));
                    assertEquals(gender, rs.getString("Gender"));
                    assertEquals(status, rs.getString("Member_Status"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            connect.rollback(); // 异常时强制回滚
        } finally {
            connect.rollback(); // 无论测试成功与否,都回滚数据
            connect.setAutoCommit(true); // 恢复默认自动提交,避免影响其他测试
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

2. 检查数据库引擎是否支持事务

如果用MySQL,确认表使用的是InnoDB引擎(MyISAM不支持事务):

  • 执行SQL查看表引擎:SHOW CREATE TABLE Member;
  • 如果是MyISAM,执行修改语句:ALTER TABLE Member ENGINE=InnoDB;

3. 用JUnit 5注解简化事务管理(Spring环境适用)

如果你的项目基于Spring,直接在测试类或方法上添加@Transactional注解,Spring会自动为测试开启事务,测试结束后自动回滚,无需手动管理连接和回滚操作:

import org.springframework.transaction.annotation.Transactional;

@Test
@Transactional
public void TestAddMember() {
    // 测试逻辑不变,无需手动处理连接和回滚
    Member member = new Member();
    String name = "lia";
    int age = 20;
    String gender = "F";
    String status = "ACTIVE";
    member.setName(name);
    member.setAge(age);
    member.setGender(gender);
    member.setStatus(status);

    memberControl.addMember(member);
    // 验证逻辑...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:41:19