也许,我做错了什么,但我找不到适合下列情况的好方法。
我想对使用下面的Spring Batch执行作业的服务进行单元测试。作业通过预先配置的AsyncTaskExecutor
在不同的线程中执行。在我的单元测试中,我想:
显然,以上所有内容都应该在一次交易中执行,但不幸的是,transactions are not propagated to new threads(我理解这背后的理由)。
我想到的想法:
Isolation.READ_UNCOMMITTED
。但这需要两种不同的配置用于测试和生产。答案 0 :(得分:3)
虽然这不是您问题的真正解决方案,但我发现可以手动在工作线程中启动 new 事务。在某些情况下,这可能就足够了。
来源:Spring programmatic transactions。
示例:
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PlatformTransactionManager txManager;
/* in a worker thread... */
public void run() {
TransactionStatus tx = txManager.getTransaction(new DefaultTransactionDefinition());
try {
entityManager.find(...)
...
entityManager.flush(...)
etc...
txManager.commit(tx);
} catch (RuntimeException e) {
txManager.rollback(tx);
}
}
答案 1 :(得分:2)
我认为最简单的解决方案是在测试执行期间使用SyncTaskExecutor配置JobLauncher - 这样就可以在与测试相同的线程中执行作业并共享事务。
可以将任务执行程序配置移动到单独的spring配置xml文件中。有两个版本 - 一个是在测试期间使用的SyncTaskExecutor,另一个是用于生产运行的AsyncTaskExecutor。
答案 2 :(得分:1)
如果您确实需要单独的配置,我建议您在配置中模板化隔离策略,并从属性文件中获取其值,这样您就不会使用一组不同的Spring配置进行测试和生成。
但我同意使用相同的政策生产用途是最好的。您的夹具数据有多大,以及有setUp()
步骤可以吹走并重建您的数据(可能来自快照,如果它是大量数据)有多么糟糕,这样您就不必依靠回滚?