在提交中途使用AbstractTransactionalJUnit4SpringContextTests [英] Using AbstractTransactionalJUnit4SpringContextTests with commit halfway through

查看:195
本文介绍了在提交中途使用AbstractTransactionalJUnit4SpringContextTests的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们想要一个运行多个线程的简单单元测试-这个想法是主线程将保存提交到数据库,然后等待辅助线程将其提取.

We want a simple unit test that runs multiple threads - the idea is that the main thread commits a save to the database, then waits for a secondary thread to pick it up.

我们发现必须为第二个线程提交事务才能查询数据库并找到项目.否则,它将不存在.

We're finding that the transaction has to be committed for the second Thread to be able to query the database and find the item. Otherwise, it won't exist.

我们正在尝试使用H2数据库来完成此任务,使用Hibernate来管理访问,并且单元测试扩展了AbstractTransactionalJUnit4SpringContextTests.

We're trying to accomplish this using an H2 database, Hibernate to manage the access, and the unit test extends AbstractTransactionalJUnit4SpringContextTests.

当我们尝试commit()现有交易时:

When we try to commit() the existing transaction:

... // Create and save our model object

sessionFactory.getCurrentSession().getTransaction().commit();
sessionFactory.getCurrentSession().beginTransaction();

... // Create and start second Thread, query, etc.

我们收到错误:

org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:484)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:521)`

但是当我们尝试仅扩展AbstractJUnit4SpringContextTests并使用@Transactional批注时:

But when we try to extend only AbstractJUnit4SpringContextTests and use the @Transactional annotations:

@TransactionConfiguration(defaultRollback=false, transactionManager="transactionManager")
@Transactional()
public class DatabaseIntegrityTest extends AbstractJUnit4SpringContextTests {

使用与上面相同的提交代码,我们将收到:

With the same commit code from above, we receive:

org.hibernate.HibernateException: No Session found for current thread
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1041)

在我们第一次致电getCurrentSession()期间.

During our first call to getCurrentSession().

是否可以通过JUnit Transactional Spring测试进行提交?

此外,当我们尝试使用AbstractTransactionalJUnit4SpringContextTests创建自己的嵌套交易时,我们收到:

Further, when we try to create our own nested transaction using AbstractTransactionalJUnit4SpringContextTests, we receive:

org.hibernate.TransactionException: nested transactions not supported
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:152)
    at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1396)

编辑并添加答案:

由于axtavt,我能够通过以下方式解决问题:

Thanks to axtavt, I was able to fix things by:

1)扩展AbstractJUnit4SpringContextTests

2)对PlatformTransactionManager使用@Autowired:

2) Using @Autowired for the PlatformTransactionManager:

   @Autowired
   protected PlatformTransactionManager transactionManager;

3)将我的交易代码放入其中:

3) Putting my transactional code inside:

TransactionStatus status = transactionManager.getTransaction(null);
... // The Model-Saving Code
transactionManager.commit(status);

推荐答案

因此,您需要在测试方法内部创建多个事务.如您所见,您不能使用AbstractTransactionalJUnit4SpringContextTests,因为它会为整个测试方法创建一个事务,而不能使用裸AbstractJUnit4SpringContextTests,因为它根本不会创建任何事务.

So, you need to create multiple transactions inside your test method. As you can see, you cannot use AbstractTransactionalJUnit4SpringContextTests, because it creates a single transaction for the whole test method, and cannot use bare AbstractJUnit4SpringContextTests, because it creates no transactions at all.

解决方案是使用AbstractJUnit4SpringContextTests并以编程方式管理测试方法中的事务.

The solution is to use AbstractJUnit4SpringContextTests and manage transactions inside your test method programmatically.

您需要将PlatformTransactionManager注入到测试中,从中创建TransactionTemplate,并使用它按照

You need to inject PlatformTransactionManager into your test, create TransactionTemplate from it and use it to demarcate your transactions as described in 11.6 Programmatic transaction management.

这篇关于在提交中途使用AbstractTransactionalJUnit4SpringContextTests的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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