この方法では、前の手順から正常にジョブを停止しました。SpringBatchジョブをStepExecutionListener afterStepメソッドから停止する方法はありますか?
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
方法でも同じアプローチがロールオーバーと認識されていない行きます。ステータスはCOMPLETEDとして記録され、その後のすべてのステップはメリーの方法で行われます(afterStepの障害検出で障害が検出されないため、最終的には恐ろしい方法で障害が発生します)。
私が考えることができる唯一のしわです:両方のリスナーは、複合リスナーを使用して同じステップにあります。
@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();
}
この実行が正しく停止するように他に何かできますか?