【问题标题】:Transaction Issue with Spring Batch JobRepository in Unit Test单元测试中 Spring Batch JobRepository 的事务问题
【发布时间】:2014-01-30 09:22:59
【问题描述】:

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

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)

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

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());
    }
}

这是 BaseTest:

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

    @Autowired
    protected JobLauncher jobLauncher;
}

【问题讨论】:

    标签: java transactions spring-batch


    【解决方案1】:

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

    查看 Spring Batch 文档的 4.3.1. Transaction Configuration for the JobRepository 部分。

    我们也遇到过这个问题,因此在找到解决方案之前,我们会避免进行事务测试。 使用多重事务管理器可能会起作用,但我还没有尝试过,请参阅How to configure mutliple transaction managers with Spring + DBUnit + JUnit

    【讨论】:

    • 感谢您提供如此有见地的评论,您所说的原因/逻辑正是我想要的。
    • 如果您想编写在测试结束时回滚的集成测试,有什么建议?
    猜你喜欢
    • 1970-01-01
    • 2020-03-02
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 2021-09-08
    • 2018-10-10
    相关资源
    最近更新 更多