【问题标题】:Why is this condition batch flow included in the infinite loop in the spring batch?为什么这个条件批处理流包含在spring批处理的无限循环中?
【发布时间】:2021-05-21 07:43:43
【问题描述】:

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

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

这里是步骤和小任务。

@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. 我想是什么让这种流动。

我的想法:Step1 没有失败,所以 start(1) -> to(1) & from(1) -> (3) -> (2) -> to(1) & from(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();
}

自己的很多实验都是在“开始”之后与“to”相关的。

我不知道为什么会这样。

是什么造成了这种差异?

【问题讨论】:

标签: spring spring-boot spring-batch batch-processing


【解决方案1】:

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

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

和

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

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

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

这意味着无论 step2 的退出代码如何,请转到 conditionalJobStep1。这就是你看到1->3->2->1->3->2->1->...的原因。

我不知道为什么会这样。是什么造成了这种差异?

当您将 step2 与 step3 翻转时,它会起作用,因为您在“*”上为 step3 定义了一个结果:.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()

这更明确,更不容易忘记传出的转换。

【讨论】:

  • 我能理解您的建议是(开始)工作,并用(从~开始~到)将案例划分为细节吗?(我问是因为我没有看到我的开始通常用于运行作业。)
  • 是的,您可以使用jobBuilderFactory.get("stepNextConditionalJob").from(stepA)... 而不是jobBuilderFactory.get("stepNextConditionalJob").start(stepA).. 开始您的流定义。如果正确定义了流,这两种语法是等效的。我推荐答案中的那个,因为它更明确,更不容易忘记转换。
  • 非常感谢。谢谢你,我完全明白了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多