2016-06-24 62 views
1

この方法では、前の手順から正常にジョブを停止しました。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(); 
} 

この実行が正しく停止するように他に何かできますか?

答えて

1

多くの実験の後、次のフロー定義では、最初のステップの後にステップを実行せずにステップリスナーからジョブを正しく停止させることができます。

return jobs.get("delivery") 
      .preventRestart() 
      .listener(failedCleanupListener) 
      .flow(firstStep) 
      .next(deliveryStep) 
      .next(handleSentStep) 
      .end() 
      .build(); 

主な違いは、flow()start()を変更しビルダー鎖の末端にFlowBuilder.end()メソッド呼び出しを追加しています。 .startメソッドから返されるSimpleJobBuilderクラスは、同様のend()メソッドを公開しません。

私はこれがジョブ実行の内部でこのような違いがなぜ分からない、と私は喜んで実際の差があるとなぜそのステップの実行ステータス・コードを照らすことができる誰かにいくつかのポイントを報奨金なりSimpleJobBuilderを使用して無視されます。しかし、私は何かを発見し、それは今のところ重要です。

関連する問題