我使用TestNG來測試使用AbstractTransactionalTestNGSpringContextTests作爲基類的持久性Spring模塊(JPA + Hibernate)。所有重要的部分@Autowired,@TransactionConfiguration,@Transactional工作得很好。TestNG多線程測試Spring @Transactional
當我嘗試在threadPoolSize = x,invocationCount = y TestNG註釋的並行線程中運行測試時,問題出現了。
WARNING: Caught exception while allowing TestExecutionListener [org.springframew[email protected]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只對主線程在所有其他線程測試沒有得到他們自己的事務實例維護交易。解決的唯一途徑是按每個方法(使用TransactionTemplate的IE)編程繼承AbstractTestNGSpringContextTests和維持交易(而不是@Transactional註釋):
@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」並查看結果是否相同 – Bozho 2010-02-04 19:50:39
註釋DaoMgr沒有效果。但AbstractTransactionalTestNGSpringContextTests是用@Transactional註釋的,所以所有的測試方法在訪問daoMgr之前啓動事務。 – 2010-02-04 20:24:24