为什么在spring批中无限循环包含这个条件批流?

Why is this condition batch flow included in the infinite loop in the spring batch?

我恶意编写了一个代码来检查批处理流程是如何工作的。

@Bean
public Step conditionalJobStep1() {
   return stepBuilderFactory.get("step1")
                            .tasklet((contribution, chunkContext) -> {
                                log.info(">>>>> This is stepNextConditionalJob Step1");
                                return RepeatStatus.FINISHED;
                            }).build();
}

@Bean
public Step conditionalJobStep2() {
   return stepBuilderFactory.get("conditionalJobStep2")
                            .tasklet((contribution, chunkContext) -> {
                                log.info(">>>>> This is stepNextConditionalJob Step2");
                                return RepeatStatus.FINISHED;
                            }).build();
}

@Bean
public Step conditionalJobStep3() {
   return stepBuilderFactory.get("conditionalJobStep3")
                            .tasklet((contribution, chunkContext) -> {
                                log.info(">>>>> This is stepNextConditionalJob Step3");
                                return RepeatStatus.FINISHED;
                            }).build();
}

这是 Steps 和 tasklets。

@Bean
public Job stepNextConditionalJob() {
    return jobBuilderFactory.get("stepNextConditionalJob")
                        .start(conditionalJobStep1())
                            .on("FAILED")
                            .to(conditionalJobStep3())
                            .on("*")
                            .end()
                        .from(conditionalJobStep1())
                            .on("*")
                            .to(conditionalJobStep3())
                            .next(conditionalJobStep2())
                            .on("*")
                            .to(conditionalJobStep1())
                            .on("*")
                            .end()
                        .end()
                            .build();
}

以上代码结果 1->3->2->1->3->2->1->..... inf。 我想是什么让这种流动。

我的想法:第 1 步没有失败,所以开始(1)-> 到(1)& 从(1)->(3)->(2)-> 到(1)& 从(1) -> (3) -> (2) -> ...

但是当我像这个作业一样只修改了 2 个数字时(在 from(step1) 之后从之前的代码中仅更改了 Step2 和 Step3 的代码)结果只是 1->2->3->Job end.

@Bean
public Job stepNextConditionalJob() {
    return jobBuilderFactory.get("stepNextConditionalJob")
                        .start(conditionalJobStep1())
                            .on("FAILED")
                            .to(conditionalJobStep3())
                            .on("*")
                            .end()
                        .from(conditionalJobStep1())
                            .on("*")
                            .to(conditionalJobStep2())
                            .next(conditionalJobStep3())
                            .on("*")
                            .to(conditionalJobStep1())
                            .on("*")
                            .end()
                        .end()
                            .build();
}

自己的很多实验都是在“start”之后跟“to”相关的。

不知道为什么会这样

是什么造成了这种差异?

您的流程未定义 * 上第 2 步的结果。你有:

.to(conditionalJobStep3())
.on("*")
.end()

.to(conditionalJobStep1())
.on("*")
.end()

但第 2 步没有这样的结构。您为步骤 2 定义的唯一结果是:

.next(conditionalJobStep2())
.on("*")
.to(conditionalJobStep1())

这意味着不管第 2 步的退出代码如何,转到 conditionalJobStep1。这就是为什么您会看到 1->3->2->1->3->2->1->....

I don't know why it works like this. What makes this difference ?

当您将第 2 步与第 3 步翻转时,它会起作用,因为您已经为第 3 步定义了“*”的结果:.to(conditionalJobStep3()).on("*").end()

我建议使用以下语法来定义每个步骤的所有结果:

 jobBuilderFactory.get("stepNextConditionalJob")
   .from(stepA).on(ExitCode1).to(StepB)
   .from(stepA).on(ExitCode2).to(StepC)
   .from(stepA).on("*").end()
   ...
   .from(stepX).on(ExitCode1).to(StepY)
   .from(stepX).on(ExitCode1).to(StepZ)
   .from(stepX).on("*").end()
 .build()

这更明确,更不容易忘记传出的过渡。