Spring Batch を掘り下げて、ジョブのさまざまなステップ間でデータを共有するにはどうすればよいですか?
これに JobRepository を使用できますか? はいの場合、どうすればそれを行うことができますか?
同じことを行う/達成する他の方法はありますか?
Spring Batch を掘り下げて、ジョブのさまざまなステップ間でデータを共有するにはどうすればよいですか?
これに JobRepository を使用できますか? はいの場合、どうすればそれを行うことができますか?
同じことを行う/達成する他の方法はありますか?
ジョブリポジトリは、ステップ間でデータを渡すために間接的に使用されます(Jean-Philippeは、データをに入れてからStepExecutionContext
、冗長な名前ExecutionContextPromotionListener
を使用してステップ実行コンテキストキーをにプロモートするのが最善の方法JobExecutionContext
です。
JobParameter
キーをに昇格させるためのリスナーもあることに注意してくださいStepExecutionContext
(さらに詳細に名前が付けられていますJobParameterExecutionContextCopyListener
)。あなたの仕事のステップが互いに完全に独立していない場合、あなたはこれらをたくさん使うことに気付くでしょう。
そうしないと、JMSキューや(天国では禁止されている)ハードコードされたファイルの場所など、さらに複雑なスキームを使用してステップ間でデータを渡すことになります。
コンテキストで渡されるデータのサイズについては、小さくすることをお勧めします(ただし、詳細については説明していません。
ステップから、データを に入れることができますStepExecutionContext
。次に、リスナーを使用して、データを からStepExecutionContext
にプロモートできますJobExecutionContext
。
これJobExecutionContext
は、次のすべての手順で使用できます。
注意: データは短くする必要があります。これらのコンテキストはJobRepository
シリアル化によって保存され、長さは制限されています (よく覚えていれば 2500 文字)。
したがって、これらのコンテキストは、文字列や単純な値を共有するには適していますが、コレクションや大量のデータを共有するには適していません。
大量のデータを共有することは、Spring Batch の哲学ではありません。Spring Batch は一連の個別のアクションであり、巨大なビジネス処理ユニットではありません。
3つのオプションがあると思います:
StepContext
して昇格さJobContext
せ、各ステップからアクセスできるようにします。サイズの制限に従う必要があります。@JobScope
し、その Bean にデータを追加し@Autowire
、必要に応じて使用します (欠点は、メモリ内構造であり、ジョブが失敗するとデータが失われ、再起動性に問題が生じる可能性があることです)。ids
にJobContext
応じてアクセスし、ジョブが正常に終了したらその一時テーブルを削除します。Java Bean オブジェクトを使用できます
このようにして、必要に応じて膨大なデータのコレクションを保存できます
別の非常に単純なアプローチです。将来の参照用にここを残します。
class MyTasklet implements Tasklet {
@Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) {
getExecutionContext.put("foo", "bar");
}
}
と
class MyOtherTasklet implements Tasklet {
@Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) {
getExecutionContext.get("foo");
}
}
getExecutionContext
ここは:
ExecutionContext getExecutionContext(ChunkContext chunkContext) {
return chunkContext.getStepContext()
.getStepExecution()
.getJobExecution()
.getExecutionContext();
}
それをスーパークラスに入れたり、インターフェースにdefault
メソッドとして入れたり、単純に s に貼り付けたりしますTasklet
。
バッチ ジョブを 1 つずつ呼び出すタスクが与えられました。各ジョブは別のジョブに依存しています。最初のジョブ結果は、結果ジョブ プログラムを実行する必要があります。ジョブ実行後にデータを渡す方法を探していました。この ExecutionContextPromotionListener が便利であることがわかりました。
1)以下のように「ExecutionContextPromotionListener」のBeanを追加しました
@Bean
public ExecutionContextPromotionListener promotionListener()
{
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
listener.setKeys( new String[] { "entityRef" } );
return listener;
}
2)次に、リスナーの1つをステップに接続しました
Step step = builder.faultTolerant()
.skipPolicy( policy )
.listener( writer )
.listener( promotionListener() )
.listener( skiplistener )
.stream( skiplistener )
.build();
3) Writer ステップの実装に参照として stepExecution を追加し、Beforestep に入力しました。
@BeforeStep
public void saveStepExecution( StepExecution stepExecution )
{
this.stepExecution = stepExecution;
}
4)ライターステップの最後に、以下のようなキーとしてステップ実行に値を入力しました
lStepContext.put( "entityRef", lMap );
5) ジョブの実行後、から値を取得し、
lExecution.getExecutionContext()
ジョブの応答として入力しました。
6) ジョブ応答オブジェクトから値を取得し、残りのジョブに必要な値を入力します。
上記のコードは、ExecutionContextPromotionListener を使用してステップから ExecutionContext にデータを昇格させるためのものです。任意のステップで実行できます。