01.Spring Batchの基本概念(ステップ)
概要
ここでは、Spring Batch使用にあたって把握しておいた方が良い基本概念を紹介したいと思います。
具体的な記述方法やテクニックなどの説明は他の章に譲ります。
Spring Batchの処理単位
Spring Batchはステップと呼ばれる単位で処理を記述していきます。
リスタートや条件分岐は、ステップ単位になります。
おそらく、このような抽象的な説明ですと分からないかと思いますので、以下の記事に進んでいただくと良いかと思います。
ステップ単位の処理イメージ
まずはイメージ図を見てみることにします。
Spring Batchにおいて処理を記述するときは、上記のようにステップ(step)と呼ばれる単位で記述されます。
例えば条件分岐する場合、ステップの中で条件分岐することはありません。
また、並行処理の場合もステップの中で並行処理をすることはありません。
つまり、ステップが処理の最小単位になります。
リスタートする場合も同様ですが、実はステップにはチャンクとよばれるパターンがあり、
チャンクを採用したステップではコミット単位でリスタート開始位置が決まります。
これについては後で説明します。
いずれにしても、設計をするときに、「1つのステップに入れる処理をどこまで細かくするか」がポイントになります。
細かくすればそれだけ、リスタートするときの開始位置が増えるので、FAILしたあとのリカバリ処理時間が短くなる可能性が高くなります。
逆にステップの処理を粗くすれば、リスタート後に処理することが増えるので時間がかかります。
とはいえ、細かくしすぎれば故障や機能拡張時に、ステップで何をしているかが分かりにくくなってしまいます。
うまくバランスをとって設計をしましょう。
ステップの種類
ステップには主に2つの種類があります。
「taskletのみのステップ」と「チャンクによるステップ」です。
以下ではそれぞれについて簡単に見ていきます。
taskletのみのステップ
taskletは、同名のインターフェースが用意されています。
Java上でimplementsして実際の処理を記述するだけです。
リスタート可能にしたい場合は、DBやファイルにごみデータが残っている可能性を考慮した処理になっている必要があります。
例えば、ワークテーブルを使用した処理であれば、taskletの処理の開始時にワークテーブルをクリアしてから開始すれば
たとえリスタートしたときにごみデータが残っていてもデータの整合性は保たれると思われます。
(このように単純にクリアすればよいケースばかりではありませんが)
いずれにしても、リスタート可能にする場合は配慮が必要です。
付け加えておきますと、Spring Batchではtaskletタイプのステップの部品をいくつか用意してくれています。
例えばシステムコマンドを実行する部品などは有名です。
チャンクによるステップ
「チャンク」という単語はSpring Batchの専門用語ではありません。
一般的なバッチ処理の言葉です。
チャンクとは、コミット単位にデータをひとまとめにしたものです。
上図では、item’を複数囲った、丸角の四角がチャンクにあたります。
SringBatchではチャンクは、item’を要素としたListとして表現します。
SpringBatchでは、データをitemと呼びますので、上記のイメージでもitemと記述しています。
具体的には通常itemはPOJOにすることを推奨しています。実際には、itemの型はジェネリックで自由に決めることができますのでHashMapなども使用できます。
おおまかな処理は以下のようになります。
【チャンクにおける処理概要】
①ItemReaderがDBやファイルなどからデータを取得します。取得したデータはItemProcessorに渡します。
②ItemProcessorは、受け取ったデータ(item)を変換します。(処理を飛ばすこともできます)
変換は、例えば「会員情報オブジェクトをitemとして受け取り、確認メールの本文文字列を作る」という変換をした場合は
変換後のデータ(item’)はStringとなります。
item’は、itemとクラスの型が同じでも、同じでなくてもかまいません。
chunk taskletは、変換後のデータ(item’)をListに溜め込みます。
③chunk taskletは、①~②を繰り返して、コミット数に達するまでListに溜め込みをします。
コミット数に達したらItemWriterにListを渡します。
④ItemWriterは、Listで受け取ったitem’をすべてDB、ファイルなどに書き込みます。メールで送信するということもできます。
失敗した場合は基本的にrollbackしますので、Listの内容すべてがDBに書き込まれるか、すべてが書き込まれないか、どちらかになります。
書き込みをする部品はいくつか既に用意されていますが、部品ごとにrollbackなどの動作は違うはずですのでよく確認して
使用しましょう。
※上記は説明を簡易にするため少しだけ簡略化しています。もし正確にitemの流れを知りたい場合は他の章を参照ください。
【チャンクにおけるリスタート】
チャンクタイプのステップに対してリスタートが発生した場合、どこから処理開始するのでしょうか?
実は、コミット単位に開始位置が決まります。
基本的にはItemReaderがコミットした数を覚えていて、リスタート時にその位置から読み込みを開始するのです。
DB処理のように数の多いバッチ処理を行う場合によく考慮された機能かと思います。
他にも使用前に確認しておいた方がよい概念を記事にしていますので読んでいただければと思います。
Created Date: 2010/01/12