私は 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
}
}
}