02.Spring Batchの基本概念(JobInstance)

概要

Spring Batchの基本概念の1つ、JobInstanceをみていきます。

具体的な動かし方、設定の仕方等は他の記事に譲ります。

JobInstanceとは

JobInstanceはSpringBatchの独自の概念のようです。

一言でいえば以下のようになります。

「起動したジョブを区別するための概念」

具体的な定義も簡単で、以下のようになります。

「ジョブIDとジョブパラメタの組み合わせが同じ場合は、同じJobInstance」

しかし、定義だけ書かれても意味が分からないかと思います。

もう少し具体的に見ていきます。

具体的例

JobInstanceはDBに保存され、IDが振られています。

IDが同じJobInstanceは同じものとみなされます。

そして、JobInstanceを理解するためにはSpringBatchの起動方法を先に説明しなければ分からないので

まずはSpringBatchの起動方法をみてみます。

【起動例】

java org.springframework.batch.core.launch.support.CommandLineJobRunner

classpath:/example/launch-context.xml job1 name=taro date=2010/01/21

(実際には1行で記述します)

CommandLineJobRunnerはSpringBatchのクラスで、main関数を持っています。

次のXMLファイルの指定は、SpringBatchのジョブの設定を記述したXMLファイルのパスです。

最後の赤字が今回の注目すべき箇所です。

"job1"は、ジョブID(ジョブ名)を表しています。

"name=taro date=2010/01/21"は、ジョブパラメタを表しています。

ここで、先述しましたJobInstanceの定義を再掲します。

「ジョブIDとジョブパラメタの組み合わせが同じ場合は、同じJobInstance」

つまり、起動例の赤字の部分が同じ場合は同じJobInstanceとなります。

例えば以下の場合、2つは同じJobInstanceです。

・"job1 name=taro date=2010/01/21"

・"job1 date=2010/01/21 name=taro"

以下のような場合は、それぞれ違うJobInstanceになります。

・"job1 date=2010/01/25 name=taro"

・"job1 date=2010/01/21 name=hanako"

・"job2 date=2010/01/25 name=taro"

このあと、JobInstanceがバッチ処理にどのように関わってくるかを見ていきます。

JobInstanceとバッチ処理の関係

基本的な考え方

JobInstanceは、実行したバッチ処理を区別するために使用されます。

SpringBatchの基本的な考え方はどうも、

「同じジョブの起動は規制する」

というようになっているようです。

(もちろん回避する方法もありますので、「基本的な考え方」という書き方をしました。)

この考え方を導入するには、「同じ起動」ということをどのように判別するかという問題が起きます。

それでSringBatchが採用した方法が、「JobInstanceが同じ」かどうかで判別する方法のようです。

基本思想

どうして、このような規制を入れるのでしょうか?

どうもSpringBatchは、「バッチは、ジョブパラメタによって処理する対象データが決まるべき」という思想を持っているようです。

例えばジョブパラメタに "date=2010/01/21" と指定した場合、2010年1月21日のデータのみが処理対象となり、

他の日付のデータには影響を与えない、といった具合です。

そのために、「同じジョブの起動は規制する」という規制を考えたのだと思われます。

対象日付のデータ処理は1度だけ実施すれば十分のはずですので、JobInstanceが同じ起動は既に成功していれば2度起動する必要は

ありません。

もちろん失敗していた場合は、リスタートできるように設計されています。

このような思想を基本に置いたためにJobInstanceが同じ場合は起動を規制することを設計に組み込んだのだと思われます。

同じジョブの起動を何度も実施したい場合でも、ジョブパラメタを変えればよいので、一応逃げ道はあります。

具体的に規制がどのように入るかを見ていった方がイメージしやすいと思いますので、以下で見ていきましょう。

以下の例では、ジョブの起動は、ジョブ名とジョブパラメタのみを記述します。

【例1: 同じジョブ名、ジョブパラメタで2回起動】

以下のジョブIDとジョブパラメタで起動したとします。

起動1: "job1 date=2010/01/21 name=taro"

無事に終了したとします。

この後、また同じ起動をしたとします。

起動2: "job1 date=2010/01/21 name=taro"

この場合、「既に完了しています」といった旨のエラーが発生し、起動できません。

【例2: 同じジョブ名、違うジョブパラメタで2回起動】

以下のジョブIDとジョブパラメタで起動したとします。

起動1: "job1 date=2010/01/21 name=taro"

無事に終了したとします。

この後、起動1とは違う起動をしたとします。

起動2: "job1 date=2010/01/22 name=taro"

この場合、問題なく起動します。

【例3: 同じジョブ名、ジョブパラメタで処理終了前に、2回目起動】

以下のジョブIDとジョブパラメタで起動したとします。

起動1: "job1 date=2010/01/21 name=taro"

まだ処理中だったとします。

この後、また同じ起動をしたとします。

起動2: "job1 date=2010/01/21 name=taro"

この場合、「ジョブが処理中です」といった旨のエラーが発生し、起動2は起動できません。

【例4: 違うジョブ名、ジョブパラメタで処理終了前に起動】

以下のジョブIDとジョブパラメタで起動したとします。

起動1: "job1 date=2010/01/21 name=taro"

まだ処理中だったとします。

この後、また違う起動をしたとします。

起動2: "job1 date=2010/01/22 name=taro"

この場合、問題なく起動します。

まとめ

JobInstanceの概念が分かりましたでしょうか?

つたない説明でしたが、もし理解いただけていればうれしいです。

おそらくJobInstanceは、起動を制限することでデータを守るために導入された概念かと思います。

しかし、実際に使ってみると分かるのですが、実際のバッチ処理と合わないこともあります。

例えば、「毎時間起動し、起動時に処理が終わっていないデータをすべて処理する」といったバッチも実際には存在します。

この場合は、ジョブパラメタは特に必要ありませんが、パラメタなしの設計にしてしまうと2回目の起動でエラーになってしまいます。

このような場合は、ダミーのジョブパラメタを用意して自動でシーケンス番号や日付などを設定する設計にすればよいです。

実装するのは面倒かと思いますが、soracaneではそのような部品も用意していますので

soracaneを使用すれば自作する必要がなくなります。

Created Date: 2010/01/12