我正在使用TestNG来测试使用AbstractTransactionTestNGSpringContextTests作为基类的持久性Spring模块(JPA + Hibernate)。所有重要的部分@Autowired,@ TransactionConfiguration,@ Transaction都能正常工作。
当我尝试使用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
}
}
}
答案 0 :(得分:2)
需要在同一个线程中启动事务,这里有更多细节:
Spring3/Hibernate3/TestNG: some tests give LazyInitializationException, some don't
答案 1 :(得分:2)
您认为这不是来自org.springframework.test.context.TestContextManager不是线程安全的(请参阅https://jira.springsource.org/browse/SPR-5863)?
当我想要并行启动Transactional TestNG测试时,我遇到了同样的问题,你可以看到Spring实际上试图将事务绑定到正确的线程。
然而,这种错误随机失败。我将AbstractTransactionalTestNGSpringContextTests扩展为:
@Override
@BeforeMethod(alwaysRun = true)
protected synchronized void springTestContextBeforeTestMethod(
Method testMethod) throws Exception {
super.springTestContextBeforeTestMethod(testMethod);
}
@Override
@AfterMethod(alwaysRun = true)
protected synchronized void springTestContextAfterTestMethod(
Method testMethod) throws Exception {
super.springTestContextAfterTestMethod(testMethod);
}
(关键是同步......)
它现在像魅力一样工作。我不能等到Spring 3.2,所以它可以完全平行!