单元测试中 Spring Batch JobRepository 的事务问题 [英] Transaction Issue with Spring Batch JobRepository in Unit Test

查看:28
本文介绍了单元测试中 Spring Batch JobRepository 的事务问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能帮我找出以下异常的解决方案,我想我只是不太了解事务传播机制,这阻碍了我理解下面显示的异常消息的真正含义,所以请帮助我了解整件事,真的非常感谢!

Could anybody help me figure out the solution to the following exception, I guess I just don't quite understand the Transaction Propagation mechanism, which hinder me from understanding the true meaning of the exception message shown below, so please, help me understanding the whole thing, thank you so much indeed!

java.lang.IllegalStateException: Existing transaction detected in JobRepository. Please fix this and try again (e.g. remove @Transactional annotations from client).
at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.java:164)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy15.createJobExecution(Unknown Source)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:111)
at TestJob.testExcelParserTasklet(TestJob.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
at org.testng.internal.MethodInvocationHelper$1.runTestMethod(MethodInvocationHelper.java:169)
at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.run(AbstractTestNGSpringContextTests.java:158)

这是导致上述异常的代码:

Here is the code resulting the above exception:

public class TestJob extends BaseTest {
@Test
public void testExcelParserTasklet() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, NoSuchJobException {
    Job job = jobRegistry.getJob("parseExcelJob");
    jobLauncher.run(job, new JobParameters());
    }
}

这是基础测试:

@ContextConfiguration("classpath:application-context.xml")
public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextTests
{
    @Autowired
    protected JobRegistry jobRegistry;

    @Autowired
    protected JobLauncher jobLauncher;
}

推荐答案

AbstractTransactionalTestNGSpringContextTests 将您的所有测试方法包装在一个事务中.Spring 批处理作业存储库不喜欢与他人共享其事务管理器.逻辑很简单,如果您在步骤失败时与步骤事务管理器共享您的作业事务管理器,它将回滚步骤和写入作业存储库的数据.这意味着您不会为作业重新启动保留数据.所以事务性单元测试的使用很棘手.

AbstractTransactionalTestNGSpringContextTests wraps all your test methods in a transaction. Spring batch job repository does not like to share its transaction manager with others. The logic is simple, if you share your job transaction manager with your step transaction manager upon step failure it will rollback both the step and the data written to the job repository. This means that you will not persist data for job restart. So the use of Transactional Unit tests is tricky.

查看4.3.1 部分.Spring Batch 文档的 JobRepository 的事务配置.

我们也遇到了这个问题,因此在找到解决方案之前,我们会避免进行事务性测试.多事务管理器的使用可能有效,但我还没有尝试过,请参阅 如何使用 Spring + DBUnit + JUnit 配置多个事务管理器

We had this issue as well, so we avoid transactional tests until we will found a solution. The use of multiply transaction managers may work, but I haven’t tried it yet see How to configure mutliple transaction managers with Spring + DBUnit + JUnit

这篇关于单元测试中 Spring Batch JobRepository 的事务问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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