在使用spring进行集成测试时,一般会使用@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)自动回滚事务,但是如果遇到REQUIRES_NEW事务,那么这个事务是不会回滚的。
1、通过覆盖其事务传播属性来完成,即如开发环境的事务属性配置如下:
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="doReweight" propagation="REQUIRES_NEW"/> <tx:method name="doClear*" propagation="REQUIRES_NEW"/> <tx:method name="doSend*" propagation="REQUIRES_NEW"/> <tx:method name="doBatchSave*" propagation="REQUIRES_NEW"/> <!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到--> <tx:method name="get*" propagation="REQUIRED" read-only="true"/> <tx:method name="count*" propagation="REQUIRED" read-only="true"/> <tx:method name="find*" propagation="REQUIRED" read-only="true"/> <tx:method name="list*" propagation="REQUIRED" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
在测试时覆盖掉即可:
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!--测试时 使用REQUIRED--> <tx:method name="doReweight" propagation="REQUIRED"/> <tx:method name="doClear*" propagation="REQUIRED"/> <tx:method name="doSend*" propagation="REQUIRED"/> <tx:method name="doBatchSave*" propagation="REQUIRED"/> <!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到--> <tx:method name="get*" propagation="REQUIRED" read-only="true"/> <tx:method name="count*" propagation="REQUIRED" read-only="true"/> <tx:method name="find*" propagation="REQUIRED" read-only="true"/> <tx:method name="list*" propagation="REQUIRED" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
但是如果是@Transactional注解的事务那么就无法解决了。
2、使用spring profile测试
还一种方式就是配置spring的profile也可以,上述配置也有点类似profile。
3、使用我提供的工具类,在测试时移除异步支持即可。
//移除异步支持 if(AopProxyUtils.isTransactional(messageApi)) { AopProxyUtils.removeTransactional(messageApi); }
此工具类请参考《使用Aop工具类诊断常见问题》
4、包级别方法测试
@Transactional(propagation = Propagation.REQUIRES_NEW) public void sendSystemMessage() { sendSystemMessageInner(); } void sendSystemMessageInner() { //测试时测试这个方法即可 }
此时测试sendSystemMessageInner即可。这种方式不管是注解还是声明都好用
其实更好的做法是spring内部提供支持,支持这样Requires_New事务的测试。
相关推荐
我们可以使用`@Transactional`注解的`propagation`属性来控制事务的传播行为,比如REQUIRED(默认)、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER和NESTED。 **声明式事务管理**是Spring的强项,它...
这个注解可以设置事务的传播行为(如REQUIRED、REQUIRES_NEW等)、隔离级别、读写模式以及超时时间。例如,`@Transactional(readOnly = true)`表示该方法仅用于查询,不修改数据,Spring会为此优化事务设置。 三、...
2、Propagation.REQUIRES_NEW 无论何时自身都会开启事务 3、Propagation.SUPPORTS 自身不会开启事务,在事务范围内则使用相同事务,否则不使用事务 4、Propagation.NOT_SUPPORTED 自身不会开启事务,...
9.Spring事务的传播机制:使用传播行为来控制事务的传播,例如REQUIRED、REQUIRES_NEW、SUPPORTS等。 10.Spring事务的回滚机制:使用回滚规则来控制事务的回滚,例如回滚异常、回滚超时等。 11.事务的隔离级别:...
4. **PROPAGATION_REQUIRES_NEW**:总是启动一个新的事务,如果当前存在事务,则将当前事务挂起。 5. **PROPAGATION_NOT_SUPPORTED**:总是以非事务方式执行,如果当前存在事务,则将当前事务挂起。 6. **...
但为了确保即使`methodB`抛出异常,`methodA`的事务仍能正确回滚,`methodB`使用了`Propagation.REQUIRES_NEW`传播属性。这意味着`methodB`将在新的独立事务中运行,即使它抛出异常,也不会影响`methodA`所在的事务...
其他的传播行为还有 `PROPAGATION_SUPPORTS`、`PROPAGATION_MANDATORY`、`PROPAGATION_REQUIRES_NEW`、`PROPAGATION_NOT_SUPPORTED`、`PROPAGATION_NEVER` 和 `PROPAGATION_NESTED`,它们分别对应不同的事务处理策略...
* TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起 编程式事务管理 编程式事务管理是指通过编写代码来管理事务。 Spring 提供了多种方式来实现编程式事务...
- **PROPAGATION_REQUIRES_NEW**:创建一个新的事务,如果当前存在事务,则把当前事务挂起。 - **PROPAGATION_NOT_SUPPORTED**:以非事务的方式执行操作,如果当前存在事务,则挂起当前的事务。 - **PROPAGATION_...
而PROPAGATION_REQUIRES_NEW则会始终创建一个新的事务,不受外部事务的影响。 接下来,我们讨论数据库事务的基本概念。数据库事务是数据库操作的基本单元,它确保了数据的一致性和完整性。事务通常包含四个特性,即...
2. **Propagation.REQUIRES_NEW**:这个属性会创建一个新的事务,并且将当前事务挂起。即使外部方法在一个事务中,内部方法也会独立地在自己的事务中运行,互不影响。 3. **Propagation.SUPPORTS**:如果当前存在...
Spring Boot可以通过`@Transactional(propagation = Propagation.REQUIRES_NEW)`确保每个线程有自己的事务上下文,即使在共享资源时也能保证事务的隔离性。此外,还可以使用`CompletableFuture`等异步编程模型来并发...
4. PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。 5. PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。 6. PROPAGATION_NEVER:总是非...
而PROPAGATION_REQUIRES_NEW则总是新建一个事务,即使在已有事务中调用,也会暂停当前事务,执行新的事务。 在实际开发中,我们还需要关注事务的隔离级别,包括READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ...
Spring定义了7种不同的传播行为,如PROPAGATION_REQUIRED(默认,如果当前存在事务,则加入,否则新建一个事务)、PROPAGATION_REQUIRES_NEW(始终新建一个事务,即使当前存在事务)等,根据业务需求选择合适的传播...
4. **PROPAGATION_REQUIRES_NEW**:无论当前是否存在事务,都创建一个新的事务,并挂起当前事务。 5. **PROPAGATION_NOT_SUPPORTED**:以非事务方式执行操作;如果当前存在事务,则挂起当前事务。 6. **PROPAGATION_...
REQUIRES_NEW:创建一个新的事务并挂起当前事务 NOT_SUPPORTED:以非事务方式执行,如果当前存在事务则将当前事务挂起 NEVER:以非事务方式进行,如果存在事务则抛出异常 NESTED:如果当前存在事务,则在嵌套事务内...
在这个例子中,`UserService`类被标记为只读事务,而`updateUser`方法使用`REQUIRES_NEW`传播行为,这意味着每次调用该方法都会开启一个新的事务,即使在其他事务中调用也不会影响原事务。 ### 总结 Spring的声明...
- **PROPAGATION_REQUIRES_NEW**:此行为总是创建一个新的事务来执行当前方法,即使当前已经存在事务,也会挂起当前事务并创建一个新的事务。这种方式适用于那些需要独立事务的操作,即使它们被调用在一个更大的事务...