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
相关产品推荐
相关产品推荐

