【发布时间】:2012-01-05 19:07:03
【问题描述】:
我正在使用 TestNG 以 AbstractTransactionalTestNGSpringContextTests 作为基类来测试持久性 Spring 模块(JPA+Hibernate)。 @Autowired、@TransactionConfiguration、@Transactional 的所有重要部分都可以正常工作。
当我尝试使用 threadPoolSize=x, invocationCount=y TestNG 注释在并行线程中运行测试时出现问题。
WARNING: Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@174202a]
to process 'before' execution of test method [testCreate()] for test instance [DaoTest] java.lang.IllegalStateException:
Cannot start new transaction without ending existing transaction: Invoke endTransaction() before startNewTransaction().
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:123)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:374)
at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextBeforeTestMethod(AbstractTestNGSpringContextTests.java:146)
... 有人遇到过这个问题吗?
代码如下:
@TransactionConfiguration(defaultRollback = false)
@ContextConfiguration(locations = { "/META-INF/app.xml" })
public class DaoTest extends AbstractTransactionalTestNGSpringContextTests {
@Autowired
private DaoMgr dm;
@Test(threadPoolSize=5, invocationCount=10)
public void testCreate() {
...
dao.persist(o);
...
}
...
更新: 似乎 AbstractTransactionalTestNGSpringContextTests 在所有其他测试线程都没有获得自己的事务实例时只为主线程维护事务。解决这个问题的唯一方法是扩展 AbstractTestNGSpringContextTests 并以编程方式维护事务(而不是 @Transactional 注释)每个方法(即使用 TransactionTemplate):
@Test(threadPoolSize=5, invocationCount=10)
public void testMethod() {
new TransactionTemplate(txManager).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// transactional test logic goes here
}
}
}
【问题讨论】:
-
为了好奇-尝试在原型范围内定义您的
DaoMgr,看看结果是否相同 -
注解 DaoMgr 无效。但是AbstractTransactionalTestNGSpringContextTests是用@Transactional注解的,所以所有的测试方法都会在daoMgr被访问之前启动事务。
标签: java multithreading unit-testing spring testng