我有以下 Spring MVC 应用程序堆栈:
控制器 -> 服务 -> DAO (Repository) -> 实体 -> MySql InnoDB
事务被配置为使用 AOP xml 配置从服务层开始,并且应用程序运行良好:
<aop:config>
<aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(* *..service.*Service.*(..))" order="1"/>
</aop:config>
<aop:aspectj-autoproxy proxy-target-class="true"/>
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
现在,我正在使用 spring-mvc-test 框架、UnitDB 等编写 Spring MVC 测试。测试类具有以下配置:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
loader=WebContextLoader.class,
locations={
"classpath:spring/testContext.xml",
"classpath:spring/testDispatcher-servlet.xml",
"classpath:spring/security.xml"
})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class })
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true)
@Transactional(propagation=Propagation.REQUIRED, rollbackFor={Exception.class})
@DatabaseSetup({"classpath:dbunit/initial-data.xml"})
测试看起来像这样:
@Test
public void testSomeController() throws Exception {
this.mockMvc.perform(get("/some/controller"));
}
基本上我想要的是在测试环境中测试(使用)现有的 Spring AOP 配置,最初设置一些数据库数据,运行测试并在测试完成后回滚所有内容。
在上述配置中,测试正在启动他们自己的事务,在给定的传播配置中,该事务在服务层遇到另一个事务,由 AOP xml 配置启动,我得到锁超时错误,因为由测试启动的事务正在等待由服务层的 AOP 配置。
我只是在编写测试,我不应该修改实际代码,只修改测试代码。我的任务是找到一种方法来回滚使用给定配置的测试所做的所有更改。
任何想法表示赞赏。
编辑
这是有问题的案例:
- 测试类启动一个新的大事务,所有测试都自动回滚。
- dbunit 用初始数据填充数据库
- 测试启动控制器测试
- 控制器调用服务层,例如保存/更新实体(由 DBUnit 在测试类的开头插入),新事务在服务层开始(由 aop:config 配置),但支持步骤 #1 中的大事务
- 繁荣,发生错误:超过锁定等待超时;尝试重启事务
我认为DBUnit插入的数据仍然没有提交,因为它在同一个事务中。我需要找到一种方法在单独的事务中使用 DBUnit 插入初始数据,但在测试结束时仍将其回滚。