Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 导致作业退出状态的Spring批处理条件流失败_Java_Spring Batch - Fatal编程技术网

Java 导致作业退出状态的Spring批处理条件流失败

Java 导致作业退出状态的Spring批处理条件流失败,java,spring-batch,Java,Spring Batch,我对执行以下操作的spring批处理流有问题(简化) 执行一个步骤(始终) 在运行时决定下一步要做什么(jobexecutiondecider) 如果决策者决定“继续”->执行更复杂的内部流 如果决策者确定“已完成”->,则不执行内部流,而只是完成作业 鉴于以下MVE: @Configuration @EnableBatchProcessing public class BatchExample { @Autowired private JobBuilderFactory jo

我对执行以下操作的spring批处理流有问题(简化)

  • 执行一个步骤(始终)
  • 在运行时决定下一步要做什么(jobexecutiondecider)
  • 如果决策者决定“继续”->执行更复杂的内部流
  • 如果决策者确定“已完成”->,则不执行内部流,而只是完成作业
  • 鉴于以下MVE:

    @Configuration
    @EnableBatchProcessing
    public class BatchExample {
    
        @Autowired
        private JobBuilderFactory jobBuilderFactory;
        @Autowired
        private StepBuilderFactory stepBuilderFactory;
    
        @Bean
        public Job exampleJob() {
            final FlowBuilder<Flow> innerFlowBuilder = new FlowBuilder<>("innerFlow");
            final Flow innerFlow = innerFlowBuilder
                .start(dummyStep("first innerflow step"))
                .next(dummyStep("second innerflow step"))
                .next(dummyStep("last innerflow step"))
                .build();
    
            final FlowBuilder<Flow> outerFlowBuilder = new FlowBuilder<>("outerFlow");
            final Flow outerFlow = outerFlowBuilder
                .start(dummyStep("always execute me"))
                .next(decide()).on("CONTINUE").to(innerFlow)
                .from(decide()).on("COMPLETED").end("COMPLETED")
                .build();
    
            return jobBuilderFactory.get("exampleJob")
                .start(outerFlow)
                .end()
                .build();
        }
    
        private Step dummyStep(String arg) {
            return stepBuilderFactory.get("step_" + arg)
                .tasklet(dummyTasklet(arg))
                .build();
        }
    
        private Tasklet dummyTasklet(String arg) {
            return new DummyTasklet(arg);
        }
    
        private DummyDecider decide() {
            return new DummyDecider();
        }
    
        class DummyTasklet implements Tasklet {
    
            private final String arg;
    
            DummyTasklet(String arg) {
                this.arg = arg;
            }
    
            @Override
            public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                System.out.println("hello from dummy tasklet: " + arg);
                return RepeatStatus.FINISHED;
            }
        }
    
        class DummyDecider implements JobExecutionDecider {
    
            @Override
            public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
                final Random random = new Random();
                final int i = random.nextInt();
    
                if (i % 2 == 0) {
                    return new FlowExecutionStatus("CONTINUE");
                } else {
                    return FlowExecutionStatus.COMPLETED;
                }
            }
        }    
    }
    
    如何在状态为“已完成”的情况下完成作业?换句话说,我在流的编码方面做错了什么

    该代码可以与spring引导应用程序一起运行

    @SpringBootApplication
    public class FlowApplication implements ApplicationRunner {
    
        public static void main(String[] args) {
            SpringApplication.run(FlowApplication.class, args);
        }
    
        @Autowired
        private Job exampleJob;
        @Autowired
        private JobLauncher jobLauncher;
    
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            jobLauncher.run(exampleJob, new JobParameters());
        }
    }
    
    编辑

    在实施建议的答案时:

    final Flow outerFlow = outerFlowBuilder
                .start(dummyStep("always execute me"))
                .on("*").to(decide())
                .from(decide()).on("CONTINUE").to(innerFlow)
                .from(decide()).on("COMPLETED").end("COMPLETED")
                .build();
    
    并迫使决策者“继续”:

    innerflow不再启动:

    Executing step: [step_always execute me]
    hello from dummy tasklet: always execute me
    Job: [FlowJob: [name=exampleJob]] completed with the following parameters: [{}] and the following status: [FAILED]
    Job: [FlowJob: [name=exampleJob]] launched with the following parameters: [{}]
    Step already complete or not restartable, so no action to execute: StepExecution: id=0, version=3, name=step_always execute me, status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0, exitDescription=
    Job: [FlowJob: [name=exampleJob]] completed with the following parameters: [{}] and the following status: [FAILED]
    

    您的
    outerFlow
    应定义如下:

    final Flow outerFlow = outerFlowBuilder
            .start(dummyStep("always execute me"))
            .on("*").to(decide())
            .from(decide()).on("CONTINUE").to(innerFlow)
            .from(decide()).on("COMPLETED").end("COMPLETED")
            .build();
    
    我用您的示例对此进行了测试(感谢您的MVE!),当决策器返回
    COMPLETED
    时,作业不会失败

    原因是,如果没有将
    dummyStep(“始终执行我”)
    步骤的所有结果路由到带有
    .on(“*”).to(decision())
    的决策器,则流定义不正确


    希望这有帮助。

    感谢您的快速帮助。“已完成”流的执行是正确的,并且确实没有失败,但是现在内部流不再工作了<代码>步骤已完成或不可重新启动,因此没有要执行的操作:步骤执行:id=0,版本=3,名称=Step\u始终执行我,作业:[FlowJob:[name=exampleJob]]已完成,具有以下参数:[{}],并且以下状态:[FAILED]多次运行程序会显示此不需要的行为@马哈茂德·本·哈辛:你知道哪里出了问题吗?我该怎么解决?这是正常的行为。除非将步骤标记为可重新启动,否则无法重新启动该步骤。因此,您需要使步骤重新启动。
    Executing step: [step_always execute me]
    hello from dummy tasklet: always execute me
    Job: [FlowJob: [name=exampleJob]] completed with the following parameters: [{}] and the following status: [FAILED]
    Job: [FlowJob: [name=exampleJob]] launched with the following parameters: [{}]
    Step already complete or not restartable, so no action to execute: StepExecution: id=0, version=3, name=step_always execute me, status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0, exitDescription=
    Job: [FlowJob: [name=exampleJob]] completed with the following parameters: [{}] and the following status: [FAILED]
    
    final Flow outerFlow = outerFlowBuilder
            .start(dummyStep("always execute me"))
            .on("*").to(decide())
            .from(decide()).on("CONTINUE").to(innerFlow)
            .from(decide()).on("COMPLETED").end("COMPLETED")
            .build();