How to halt a Spring Batch job from a StepExecutionListener afterStep method?(如何从StepExecutionListener After Step方法暂停Spring批处理作业?)
问题描述
我已使用此方法成功地从前一步停止了作业。
public class FirstListener implements StepExecutionListener {
@Override
public void beforeStep(StepExecution stepExecution) {
boolean shouldRun = shouldJobRun();
if (!shouldRun) {
// listeners will still work, but any other step logic (reader, processor, writer) will not happen
stepExecution.setTerminateOnly();
stepExecution.setExitStatus(new ExitStatus("STOPPED", "Job should not be run right now."));
LOGGER.warn(duplicate_message);
}
}
代码是为了简洁性/清晰性进行了调整,但这就是要点。调用stepExecution.setTerminateOnly()和stepExecution.setExitStatus()就足以让Spring Batch暂停作业,不执行任何后续步骤。状态已正确记录在BATCH_JOB_EXECUTION表中
EXIT_MESSAGE STATUS
org.springframework.batch.core.JobInterruptedException STOPPED
但是,afterStep方法中的相同方法会被翻转,无法识别。状态被记录为已完成,并且所有后续步骤都会顺其自然地进行(最终以各自可怕的方式失败,因为After Step中的故障检测正在检测故障,因此它们不必这样做)。
public class SecondListener implements StepExecutionListener {
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
if (stepExecution.getExitStatus().getExitCode().equals(ExitStatus.STOPPED.getExitCode())) {
return stepExecution.getExitStatus();
}
if (everythingIsOkay()) {
return stepExecution.getExitStatus();
}
String failureMessage = "Something bad happened.";
LOGGER.error(failureMessage);
ExitStatus exitStatus = new ExitStatus(ExitStatus.FAILED.getExitCode(), failureMessage);
stepExecution.setExitStatus(exitStatus);
stepExecution.setTerminateOnly();
return exitStatus;
}
这是我能想到的唯一问题:两个监听器使用复合监听器处于同一步骤。
@Bean(name = "org.springframework.batch.core.StepExecutionListener-compositeListener")
@StepScope
public StepExecutionListener compositeListener() {
CompositeStepExecutionListener listener = new CompositeStepExecutionListener();
List<StepExecutionListener> listeners = Lists.newArrayList(secondListener());
if (jobShouldHaveFirstListener()) {
listeners.add(0, firstListener()); // prepend; delegates are called in order
}
listener.setListeners(listeners.toArray());
return listener;
}
public Step firstStep() {
return stepBuilderFactory.get("firstStep")
.listener(compositeListener)
// Small batch size for frequency capping, which happens in the writer, before analytics get written
.<Recipient, Recipient>chunk(500)
.reader(rawRecipientInputFileItemReader)
.processor(recipientItemProcessor)
.writer(recipientWriter)
.throttleLimit(2)
.build();
}
@Bean(name = "org.springframework.batch.core.Job-delivery")
public Job deliveryJob() {
return jobs.get("delivery")
.preventRestart()
.start(firstStep)
.next(deliveryStep)
.next(handleSentStep)
.listener(failedCleanupListener)
.build();
}
是否可以执行其他操作以使此执行正确停止?
推荐答案
经过多次试验,我发现下面的流定义将允许从步骤侦听器正确停止作业,而无需在第一步之后执行步骤。
return jobs.get("delivery")
.preventRestart()
.listener(failedCleanupListener)
.flow(firstStep)
.next(deliveryStep)
.next(handleSentStep)
.end()
.build();
主要区别在于将start()更改为flow(),并将FlowBuilder.end()方法调用添加到构建器链的末尾。从.start方法返回的SimpleJobBuilder类没有公开类似的end()方法。
我不知道为什么这会在作业执行的内部造成如此大的差异,我很乐意向能够说明实际差异是什么以及为什么使用SimpleJobBuilder忽略步骤执行状态代码的人提供一些要点。但我发现了一些有用的东西,这就是目前最重要的。
这篇关于如何从StepExecutionListener After Step方法暂停Spring批处理作业?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何从StepExecutionListener After Step方法暂停Spring批处理作业?
基础教程推荐
- 修改 void 函数的输入参数,然后读取 2022-01-01
- Struts2 URL 无法访问 2022-01-01
- RabbitMQ:消息保持“未确认"; 2022-01-01
- 存储 20 位数字的数据类型 2022-01-01
- REST Web 服务返回 415 - 不支持的媒体类型 2022-01-01
- 无法复制:“比较方法违反了它的一般约定!" 2022-01-01
- Spring AOP错误无法懒惰地为此建议构建thisJoinPoin 2022-09-13
- 使用堆栈算法进行括号/括号匹配 2022-01-01
- 问题http://apache.org/xml/features/xinclude测试日志4j 2 2022-01-01
- 如何对 Java Hashmap 中的值求和 2022-01-01
