使用createOptionFlowUsingSteps与JobExecutionDecider的流程重复问题
问题描述
我在JobConfiguration中用createOptionFlowUsingSteps定义了两个流程,需求如下:
- 第一个流程必须始终执行
- 若第一个流程生成空输出文件,作业立即终止
- 若输出文件有内容,则启动第二个流程
当前异常:空文件时作业能正常终止,但文件有内容时,作业会重复执行第一个流程,完全不会触发第二个流程。
配置代码
List<Step> startSteps = Arrays.asList( // shp294SetupStep, // 0 deleteFileStep, // 1 callM204Step// 2 ); List<Step> endSteps = Arrays.asList( // putFtpStep, // 0 cdtx500SetupStep, // 1 getFtpStep, // 2 callCobolStep, // 3 callSystemwareStep, //4 cdtx510SetupStep, // 5 getFtpStep, // 6 callCobolStep, // 7 putFtpStep// 8 ); List<Integer> emptyFileRequiredSteps = Arrays.asList(0); List<Integer> requiredSteps = Arrays.asList(1, 5); Flow startStepFlow = shpcdwrdStepHelper.createOptionalFlowUsingSteps(startSteps, emptyFileRequiredSteps); Flow endStepFlow = shpcdwrdStepHelper.createOptionalFlowUsingSteps(endSteps, requiredSteps); return jobFactory.get(JOB_NAME) // .incrementer(new RunIdIncrementer()) // .listener(new JobResultListener()) // .start(startStepFlow) // .next(optionalFlowDecider()).on(OptionalFlowDecider.ON_EMPTY_FILE).end() // .from(optionalFlowDecider()).on(FlowExecutionStatus.COMPLETED.getName()).to(endStepFlow) .build() // .build(); //
问题原因
问题出在流程分支的定义逻辑上:from(optionalFlowDecider())没有指定该分支的前置节点,Spring Batch流程构建器会默认将分支连接到作业的起始点(也就是startStepFlow)。当决策器返回COMPLETED状态时,作业会重新执行第一个流程,形成循环,永远到不了第二个流程。
修复方案
调整流程分支的定义方式,明确分支的前置节点,或者使用链式分支语法,让决策器的两个分支分别对应终止作业和执行第二个流程:
修复后的代码示例
return jobFactory.get(JOB_NAME) // .incrementer(new RunIdIncrementer()) // .listener(new JobResultListener()) // .start(startStepFlow) // .next(optionalFlowDecider()) .on(OptionalFlowDecider.ON_EMPTY_FILE).end() // 空文件时终止作业 .on(FlowExecutionStatus.COMPLETED.getName()).to(endStepFlow) // 文件有内容时执行第二个流程 .end() // 结束分支定义 .build();
或者也可以明确指定from的前置节点为startStepFlow:
return jobFactory.get(JOB_NAME) // .incrementer(new RunIdIncrementer()) // .listener(new JobResultListener()) // .start(startStepFlow) // .next(optionalFlowDecider()).on(OptionalFlowDecider.ON_EMPTY_FILE).end() // .from(startStepFlow).on(FlowExecutionStatus.COMPLETED.getName()).to(endStepFlow) .build();
这样修改后,当第一个流程执行完成且文件非空时,会直接跳转至第二个流程,不会重复执行第一个流程。
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

