我们想要一个运行多个线程的简单单元测试-这个想法是主线程将保存提交到数据库,然后等待辅助线程将其拾取。
我们发现必须为第二个线程提交事务才能查询数据库并找到项目。否则,它将不存在。
我们正在尝试使用H2数据库,由Hibernate管理访问以及单元测试扩展来完成此任务AbstractTransactionalJUnit4SpringContextTests。
AbstractTransactionalJUnit4SpringContextTests
当我们尝试commit()现有交易时:
commit()
... // 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注释时:
AbstractJUnit4SpringContextTests
@Transactional
@TransactionConfiguration(defaultRollback=false, transactionManager="transactionManager") @Transactional() public class DatabaseIntegrityTest extends AbstractJUnit4SpringContextTests {
使用上面相同的提交代码,我们将收到:
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()。
getCurrentSession()
有没有办法在JUnit事务性Spring测试中进行提交?
此外,当我们尝试使用创建嵌套事务时AbstractTransactionalJUnit4SpringContextTests,我们收到:
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,我得以通过以下方式解决问题:
axtavt
1)扩展 AbstractJUnit4SpringContextTests
2)将@Autowired用于PlatformTransactionManager:
PlatformTransactionManager
@Autowired protected PlatformTransactionManager transactionManager;
3)将我的交易代码放入其中:
TransactionStatus status = transactionManager.getTransaction(null); ... // The Model-Saving Code transactionManager.commit(status);
因此,您需要在测试方法内创建多个事务。如您所见,您不能使用AbstractTransactionalJUnit4SpringContextTests,因为它会为整个测试方法创建一个事务,而不能使用nude AbstractJUnit4SpringContextTests,因为它根本不会创建任何事务。
解决方案是以AbstractJUnit4SpringContextTests编程方式在测试方法内部使用和管理事务。
您需要按照11.6程序化交易管理中所述注入PlatformTransactionManager测试,TransactionTemplate从测试中创建并使用它来划分事务。
TransactionTemplate