使用Spring @Transactional进行TestNG多线程测试 [英] TestNG multithreaded test with Spring @Transactional

查看:1001
本文介绍了使用Spring @Transactional进行TestNG多线程测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用TestNG来测试使用AbstractTransactionTestNGSpringContextTests作为基类的持久性Spring模块(JPA + Hibernate)。所有重要的部分@Autowired,@ TransactionConfiguration,@ Transaction都可以正常工作。

I am using TestNG to test persistence Spring modules (JPA+Hibernate) using AbstractTransactionalTestNGSpringContextTests as a base class. All important parts @Autowired, @TransactionConfiguration, @Transactional work just fine.

当我尝试使用threadPoolSize = x,invocationCount =并行线程运行测试时出现问题y TestNG注释。

The problem comes when I am trying to run test in parallel threads with threadPoolSize=x, invocationCount=y TestNG annotation.

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)

...
有没有人遇到这个问题?

... Has anybody faced this problem?

这是代码:

@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,并按每个方法(即使用TransactionTemplate)以编程方式(而不是@Transactional注释)维护事务:

Update: It seems that AbstractTransactionalTestNGSpringContextTests maintains transaction only for main thread when all other test threads don't get their own transaction instance. The only way to solve that is to extend AbstractTestNGSpringContextTests and maintain transaction programmatically (instead of @Transactional annotation) per each method (i.e. with 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
        }
    }
}


推荐答案

交易需要在同一个线程中启动,更多细节如下:

The transaction needs to be started in the same thread, here are more details:

Spring3 / Hibernate3 / TestNG:一些测试给出LazyInitializationException,有些不要

这篇关于使用Spring @Transactional进行TestNG多线程测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆