返回Spring Batch中的上一步

我想使用Spring Batch实现类似于以下的Job:

Step1 -----> Step2 --> End
  ^            |
  |            |
   ------------

在步骤2中的某些条件下,由步骤2的自定义ExitCode确定,或者再次启动步骤1,然后再启动步骤2,或者处理将结束 .

我想象的是这样的:

return jobBuilderFactory.get("jobName").incrementer(new RunIdIncrementer())
                .start(step1()).next(step2())
                    .on("condition1").end()
                .from(step1())
                    .on("condition2").to(step1()).end().build();

但显然,在Step2通过Step2的condition2处理后,Step2将不会再次启动 .

如何实现这样的递归批处理?

EDIT: 我设法得到一个解决方案,但是,我还不知道它是否只是一个肮脏的,因为它似乎只是简单:

jobBuilderFactory.get("jobName")
            .flow(step1())
            .next(step2())
                .on("launchStep1Again")
                    .to(step1())
            .from(step2())
                .on("endJobExecution")
                    .end().build().build();

因此,从使用Fluent API的.start()方法到其.flow()方法的简单更改似乎可以解决问题 .

回答(2)

2 years ago

SpringBatch不用于处理递归循环 . 虽然您可能能够破解它,但在遇到故障和重新启动时会遇到问题 .

SpringBatch将读取器的当前“位置”存储在其执行上下文中的步骤;为了能够在最后一次崩溃的位置重新启动作业 .

因此,在重新启动作业的情况下,SpringBatch将假定这是该作业的第一次执行 .

根据您的工作结构,这可能不是问题,但您必须牢记这一点 .

在我看来,更好的解决方案是在一个处理起始工作的单独类中实现处理作业外部的循环 .

以下两个问题的答案可能有助于提出这样的解决方案:

Make a spring-batch job exit with non-zero code if an exception is thrown

Reset state before each Spring scheduled (@Scheduled) run

2 years ago

我认为您可以扩展StepExecutionListenerSupport类并修改配置,如下所示:

<step id="step1" next="step2">
    <tasklet ref="step1Tasklet" allow-start-if-complete="true"/>
</step>
<step id="step2">
    <tasklet ref="step2Tasklet"/>
    <listeners>
        <listener ref="myListener"/>
    </listeners>
    <next on="Back" to="step1"/>
</step>

public class MyListener extends StepExecutionListenerSupport {
    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        if(wantToLoop) {
            return new ExitStatus("Back");
        } else {
            return stepExecution.getExitStatus();
        }
    }
}