SpringBoot 2.3.11集成JUnit5时PROPAGATION_REQUIRES_NEW失效问题
SpringBoot 2.3.11 + JUnit5 测试环境事务工具类执行失败的解决办法
问题根源分析
- 低级拼写错误:代码里的
cache(Exception e)应为catch(Exception e),transactinUtil.rollback()的变量名拼写错误(应为transactionUtil),业务环境可能未触发异常所以没暴露,测试环境触发异常后直接报错。 - 测试上下文未初始化:测试类未加载Spring上下文,导致
SpringUtil.getBean("dataSource")无法获取到数据源实例。 - 手动实例化事务管理器不兼容测试环境:业务环境中数据源由Spring正常管理,但测试环境(如使用H2内存库)下,手动
new DataSourceTransactionManager(dataSource)无法和Spring测试事务机制联动,导致事务无法正常执行。 - 工具类未被Spring管理:手动
new TransactionUtil()创建实例,而非依赖Spring注入,内部事务状态无法和测试上下文同步。
具体修复步骤
1. 修正代码拼写错误
先把异常捕获和变量名的低级错误改掉:
TransactionUtil transactionUtil = null; try { transactionUtil = new TransactionUtil(); transactionUtil.begin(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 业务逻辑代码 transactionUtil.commit(); } catch(Exception e) { if(transactionUtil != null) { transactionUtil.rollback(); } }
2. 让测试类加载Spring上下文
在JUnit5测试类上添加@SpringBootTest注解,确保测试环境初始化完整的Spring上下文:
@SpringBootTest class YourBusinessServiceTest { // 测试方法编写 }
3. 改造TransactionUtil,交由Spring管理
不再手动创建事务管理器,改为通过Spring注入PlatformTransactionManager,同时把工具类声明为Spring组件:
@Component public class TransactionUtil { private final PlatformTransactionManager transactionManager; private TransactionStatus status; // 构造方法注入事务管理器 public TransactionUtil(PlatformTransactionManager transactionManager) { this.transactionManager = transactionManager; } public void begin(int propagation) { DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition(); transactionDefinition.setPropagationBehavior(propagation); transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT); status = transactionManager.getTransaction(transactionDefinition); } public void commit() { if(status != null) { transactionManager.commit(status); } } public void rollback() { if(status != null) { transactionManager.rollback(status); } } }
4. 在测试类中注入TransactionUtil
不再手动new实例,通过Spring依赖注入获取工具类:
@SpringBootTest class YourBusinessServiceTest { @Autowired private TransactionUtil transactionUtil; @Test void testTransactionalOperation() { try { transactionUtil.begin(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 测试业务逻辑 transactionUtil.commit(); } catch(Exception e) { transactionUtil.rollback(); throw e; } } }
5. 测试事务自动回滚配置(可选)
如果需要测试用例执行后自动回滚事务,可在测试类或方法上添加@Transactional注解(JUnit5 + SpringBoot默认会自动回滚测试事务):
@SpringBootTest @Transactional class YourBusinessServiceTest { // ... }
内容的提问来源于stack exchange,提问作者freedom
相关产品推荐
相关产品推荐

