付録 A: メタデータスキーマ

概要

Spring Batch メタデータテーブルは、Java で表すドメインオブジェクトと厳密に一致します。例: JobInstanceJobExecutionJobParametersStepExecution はそれぞれ BATCH_JOB_INSTANCEBATCH_JOB_EXECUTIONBATCH_JOB_EXECUTION_PARAMSBATCH_STEP_EXECUTION にマップされます。ExecutionContext は、BATCH_JOB_EXECUTION_CONTEXT と BATCH_STEP_EXECUTION_CONTEXT の両方にマップされます。JobRepository は、各 Java オブジェクトを正しいテーブルに保存および格納するロールを果たします。この付録では、メタデータテーブルの詳細と、メタデータテーブルの作成時に行われた設計上の決定の多くについて説明します。以下のさまざまなテーブル作成ステートメントを表示するときは、使用されるデータ型が可能な限り一般的であることを理解することが重要です。Spring Batch は、例として多くのスキーマを提供していますが、個々のデータベースベンダーがデータ型を処理する方法が異なるため、すべてのスキーマのデータ型が異なります。次のイメージは、6 つのテーブルすべての ERD モデルとそれらの相互関連を示しています。

Spring Batch Meta-Data ERD
図 1: Spring Batch メタデータ ERD

DDL スクリプトの例

Spring Batch コア JAR ファイルには、多数のデータベースプラットフォームのリレーショナルテーブルを作成するサンプルスクリプトが含まれています(これらは、ジョブリポジトリファクトリ Bean または同等のネームスペースによって自動検出されます)。これらのスクリプトは、そのまま使用することも、必要に応じて追加のインデックスと制約を使用して変更することもできます。ファイル名の形式は schema-*.sql です。ここで、"*" はターゲットデータベースプラットフォームの短縮名です。スクリプトは、パッケージ org.springframework.batch.core にあります。

移行 DDL スクリプト

Spring Batch は、バージョンをアップグレードするときに実行する必要がある移行 DDL スクリプトを提供します。これらのスクリプトは、org/springframework/batch/core/migration の Core Jar ファイルにあります。移行スクリプトは、導入されたバージョン番号に対応するフォルダーに編成されます。

  • 2.22.2 より前のバージョンからバージョン 2.2 に移行する場合に必要なスクリプトが含まれています

  • 4.14.1 より前のバージョンからバージョン 4.1 に移行する場合に必要なスクリプトが含まれています

バージョン

この付録で説明するデータベーステーブルの多くには、バージョン列が含まれています。Spring Batch はデータベースの更新を処理するときに楽観的ロック戦略を採用しているため、この列は重要です。これは、レコードが「タッチ」(更新)されるたびに、バージョン列の値が 1 ずつ増加することを意味します。リポジトリが値を保存するために戻ったときに、バージョン番号が変更された場合、OptimisticLockingFailureException がスローされ、同時アクセスでエラーが発生したことが示されます。このチェックは、異なるバッチジョブが異なるマシンで実行されている場合でも、すべて同じデータベーステーブルを使用するため、必要です。

識別

BATCH_JOB_INSTANCEBATCH_JOB_EXECUTIONBATCH_STEP_EXECUTION には、それぞれ _ID で終わる列が含まれています。これらのフィールドは、それぞれのテーブルの主キーとして機能します。ただし、これらはデータベースで生成されたキーではありません。むしろ、それらは別々のシーケンスによって生成されます。これが必要なのは、ドメインオブジェクトの 1 つをデータベースに挿入した後、与えられたキーを実際のオブジェクトに設定して、Java で一意に識別できるようにする必要があるためです。新しいデータベースドライバ(JDBC 3.0 以降)は、データベースで生成されたキーでこの機能をサポートします。ただし、その機能を必要とするのではなく、シーケンスが使用されます。スキーマの各バリエーションには、次のステートメントの形式が含まれています。

CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
CREATE SEQUENCE BATCH_JOB_EXECUTION_SEQ;
CREATE SEQUENCE BATCH_JOB_SEQ;

多くのデータベースベンダーはシーケンスをサポートしていません。これらの場合、MySQL の次のステートメントのような回避策が使用されます。

CREATE TABLE BATCH_STEP_EXECUTION_SEQ (ID BIGINT NOT NULL) type=InnoDB;
INSERT INTO BATCH_STEP_EXECUTION_SEQ values(0);
CREATE TABLE BATCH_JOB_EXECUTION_SEQ (ID BIGINT NOT NULL) type=InnoDB;
INSERT INTO BATCH_JOB_EXECUTION_SEQ values(0);
CREATE TABLE BATCH_JOB_SEQ (ID BIGINT NOT NULL) type=InnoDB;
INSERT INTO BATCH_JOB_SEQ values(0);

上記の場合、各シーケンスの代わりにテーブルが使用されます。Spring コアクラス MySQLMaxValueIncrementer は、同様の機能を提供するために、このシーケンスの 1 列をインクリメントします。

BATCH_JOB_INSTANCE

BATCH_JOB_INSTANCE テーブルは、JobInstance に関連するすべての情報を保持し、階層全体の最上位として機能します。次の汎用 DDL ステートメントを使用して作成します。

CREATE TABLE BATCH_JOB_INSTANCE  (
  JOB_INSTANCE_ID BIGINT  PRIMARY KEY ,
  VERSION BIGINT,
  JOB_NAME VARCHAR(100) NOT NULL ,
  JOB_KEY VARCHAR(2500)
);

次のリストでは、表の各列について説明します。

  • JOB_INSTANCE_ID: インスタンスを識別する一意の ID。これは主キーでもあります。この列の値は、JobInstance で getId メソッドを呼び出して取得できる必要があります。

  • VERSION: バージョンを参照してください。

  • JOB_NAMEJob オブジェクトから取得したジョブの名前。インスタンスを識別する必要があるため、null であってはなりません。

  • JOB_KEY: 同じジョブの個別のインスタンスを相互に一意に識別する JobParameters の直列化。(同じジョブ名の JobInstances は、異なる JobParameters を持つ必要があるため、異なる JOB_KEY 値を持つ必要があります)。

BATCH_JOB_EXECUTION_PARAMS

BATCH_JOB_EXECUTION_PARAMS テーブルは、JobParameters オブジェクトに関連するすべての情報を保持します。Job に渡される 0 個以上のキー / 値ペアが含まれ、ジョブが実行されたパラメーターの記録として機能します。ジョブの ID の生成にコントリビュートする各パラメーターについて、IDENTIFYING フラグは true に設定されます。テーブルは非正規化されていることに注意してください。次のように、型ごとに個別のテーブルを作成するのではなく、型を示す列を持つテーブルが 1 つあります。

CREATE TABLE BATCH_JOB_EXECUTION_PARAMS  (
	JOB_EXECUTION_ID BIGINT NOT NULL ,
	TYPE_CD VARCHAR(6) NOT NULL ,
	KEY_NAME VARCHAR(100) NOT NULL ,
	STRING_VAL VARCHAR(250) ,
	DATE_VAL DATETIME DEFAULT NULL ,
	LONG_VAL BIGINT ,
	DOUBLE_VAL DOUBLE PRECISION ,
	IDENTIFYING CHAR(1) NOT NULL ,
	constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
	references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
);

次のリストで各列について説明します。

  • JOB_EXECUTION_ID: パラメーターエントリが属するジョブの実行を示す BATCH_JOB_EXECUTION テーブルの外部キー。実行ごとに複数の行(つまり、キー / 値のペア)が存在する場合があることに注意してください。

  • TYPE_CD: 格納されている値の型の文字列表現。文字列、日付、long、double のいずれかです。型は既知である必要があるため、null にすることはできません。

  • KEY_NAME: パラメーターキー。

  • STRING_VAL: 型がストリングの場合のパラメーター値。

  • DATE_VAL: 型が日付の場合のパラメーター値。

  • LONG_VAL: 型が長い場合のパラメーター値。

  • DOUBLE_VAL: 型が double の場合のパラメーター値。

  • IDENTIFYING: パラメーターが関連する JobInstance のアイデンティティに貢献したかどうかを示すフラグ。

このテーブルには主キーがないことに注意してください。これは、フレームワークが 1 つを使用しないため、フレームワークを必要としないためです。必要に応じて、フレームワーク自体に課題を引き起こすことなく、データベースで生成されたキーとともにプライマリキーを追加できます。

BATCH_JOB_EXECUTION

BATCH_JOB_EXECUTION テーブルは、JobExecution オブジェクトに関連するすべての情報を保持します。Job が実行されるたびに、このテーブルには常に新しい JobExecution と新しい行が常に存在します。次のリストは、BATCH_JOB_EXECUTION テーブルの定義を示しています。

CREATE TABLE BATCH_JOB_EXECUTION  (
  JOB_EXECUTION_ID BIGINT  PRIMARY KEY ,
  VERSION BIGINT,
  JOB_INSTANCE_ID BIGINT NOT NULL,
  CREATE_TIME TIMESTAMP NOT NULL,
  START_TIME TIMESTAMP DEFAULT NULL,
  END_TIME TIMESTAMP DEFAULT NULL,
  STATUS VARCHAR(10),
  EXIT_CODE VARCHAR(20),
  EXIT_MESSAGE VARCHAR(2500),
  LAST_UPDATED TIMESTAMP,
  JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL,
  constraint JOB_INSTANCE_EXECUTION_FK foreign key (JOB_INSTANCE_ID)
  references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
) ;

次のリストで各列について説明します。

  • JOB_EXECUTION_ID: この実行を一意に識別する主キー。この列の値は、JobExecution オブジェクトの getId メソッドを呼び出すことで取得できます。

  • VERSION: バージョンを参照してください。

  • JOB_INSTANCE_IDBATCH_JOB_INSTANCE テーブルからの外部キー。この実行が属するインスタンスを示します。インスタンスごとに複数の実行がある場合があります。

  • CREATE_TIME: 実行が作成された時刻を表すタイムスタンプ。

  • START_TIME: 実行が開始された時刻を表すタイムスタンプ。

  • END_TIME: 成功または失敗に関係なく、実行が終了した時間を表すタイムスタンプ。ジョブが現在実行されていないときにこの列の空の値は、何らかの型のエラーがあり、フレームワークが失敗する前に最後の保存を実行できなかったことを示します。

  • STATUS: 実行のステータスを表す文字列。これは、COMPLETEDSTARTED などの場合があります。この列のオブジェクト表現は、BatchStatus 列挙です。

  • EXIT_CODE: 実行の終了コードを表す文字列。コマンドラインジョブの場合、これは数値に変換される場合があります。

  • EXIT_MESSAGE: ジョブの終了方法のより詳細な説明を表す文字列。障害が発生した場合、これには可能な限り多くのスタックトレースが含まれます。

  • LAST_UPDATED: この実行が最後に保持された時間を表すタイムスタンプ。

BATCH_STEP_EXECUTION

BATCH_STEP_EXECUTION テーブルには、StepExecution オブジェクトに関連するすべての情報が保持されます。このテーブルは、多くの点で BATCH_JOB_EXECUTION テーブルと類似しており、作成された各 JobExecution の Step ごとに少なくとも 1 つのエントリが常にあります。次のリストは、BATCH_STEP_EXECUTION テーブルの定義を示しています。

CREATE TABLE BATCH_STEP_EXECUTION  (
  STEP_EXECUTION_ID BIGINT  PRIMARY KEY ,
  VERSION BIGINT NOT NULL,
  STEP_NAME VARCHAR(100) NOT NULL,
  JOB_EXECUTION_ID BIGINT NOT NULL,
  START_TIME TIMESTAMP NOT NULL ,
  END_TIME TIMESTAMP DEFAULT NULL,
  STATUS VARCHAR(10),
  COMMIT_COUNT BIGINT ,
  READ_COUNT BIGINT ,
  FILTER_COUNT BIGINT ,
  WRITE_COUNT BIGINT ,
  READ_SKIP_COUNT BIGINT ,
  WRITE_SKIP_COUNT BIGINT ,
  PROCESS_SKIP_COUNT BIGINT ,
  ROLLBACK_COUNT BIGINT ,
  EXIT_CODE VARCHAR(20) ,
  EXIT_MESSAGE VARCHAR(2500) ,
  LAST_UPDATED TIMESTAMP,
  constraint JOB_EXECUTION_STEP_FK foreign key (JOB_EXECUTION_ID)
  references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ;

次のリストは、各列について説明しています。

  • STEP_EXECUTION_ID: この実行を一意に識別する主キー。この列の値は、StepExecution オブジェクトの getId メソッドを呼び出して取得できるはずです。

  • VERSION: バージョンを参照してください。

  • STEP_NAME: この実行が属するステップの名前。

  • JOB_EXECUTION_IDBATCH_JOB_EXECUTION テーブルからの外部キー。これは、この StepExecution が属する JobExecution を示します。特定の Step 名に対して、特定の JobExecution に対して 1 つの StepExecution のみが存在する場合があります。

  • START_TIME: 実行が開始された時刻を表すタイムスタンプ。

  • END_TIME: 成功または失敗に関係なく、実行が終了した時刻を表すタイムスタンプ。この列の空の値は、ジョブが現在実行されていなくても、何らかの型のエラーがあり、フレームワークが失敗する前に最後の保存を実行できなかったことを示します。

  • STATUS: 実行のステータスを表す文字列。これは、COMPLETEDSTARTED などの場合があります。この列のオブジェクト表現は、BatchStatus 列挙です。

  • COMMIT_COUNT: この実行中にステップがトランザクションをコミットした回数。

  • READ_COUNT: この実行中に読み取られたアイテムの数。

  • FILTER_COUNT: この実行から除外されたアイテムの数。

  • WRITE_COUNT: この実行中に書き込まれコミットされたアイテムの数。

  • READ_SKIP_COUNT: この実行中に読み取り時にスキップされたアイテムの数。

  • WRITE_SKIP_COUNT: この実行中に書き込み時にスキップされたアイテムの数。

  • PROCESS_SKIP_COUNT: この実行中の処理中にスキップされたアイテムの数。

  • ROLLBACK_COUNT: この実行中のロールバックの数。このカウントには、再試行のロールバックやスキップリカバリ手順のロールバックなど、ロールバックが発生するたびに含まれることに注意してください。

  • EXIT_CODE: 実行の終了コードを表す文字列。コマンドラインジョブの場合、これは数値に変換される場合があります。

  • EXIT_MESSAGE: ジョブの終了方法のより詳細な説明を表す文字列。障害が発生した場合、これには可能な限り多くのスタックトレースが含まれます。

  • LAST_UPDATED: この実行が最後に保持された時間を表すタイムスタンプ。

BATCH_JOB_EXECUTION_CONTEXT

BATCH_JOB_EXECUTION_CONTEXT テーブルは、Job の ExecutionContext に関連するすべての情報を保持します。JobExecution ごとに 1 つの JobExecutionContext があり、特定のジョブの実行に必要なすべてのジョブレベルのデータが含まれています。このデータは通常、JobInstance が「中断したところから開始」できるように、障害後に取得する必要がある状態を表します。次のリストは、BATCH_JOB_EXECUTION_CONTEXT テーブルの定義を示しています。

CREATE TABLE BATCH_JOB_EXECUTION_CONTEXT  (
  JOB_EXECUTION_ID BIGINT PRIMARY KEY,
  SHORT_CONTEXT VARCHAR(2500) NOT NULL,
  SERIALIZED_CONTEXT CLOB,
  constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
  references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ;

次のリストで各列について説明します。

  • JOB_EXECUTION_ID: コンテキストが属する JobExecution を表す外部キー。特定の実行に複数の行が関連付けられている場合があります。

  • SHORT_CONTEXTSERIALIZED_CONTEXT の文字列バージョン。

  • SERIALIZED_CONTEXT: 直列化されたコンテキスト全体。

BATCH_STEP_EXECUTION_CONTEXT

BATCH_STEP_EXECUTION_CONTEXT テーブルは、Step の ExecutionContext に関連するすべての情報を保持します。StepExecution ごとに 1 つの ExecutionContext があり、特定のステップ実行のために永続化する必要があるすべてのデータが含まれています。通常、このデータは、障害の後に取得する必要がある状態を表すため、JobInstance は「中断したところから開始」できます。次のリストは、BATCH_STEP_EXECUTION_CONTEXT テーブルの定義を示しています。

CREATE TABLE BATCH_STEP_EXECUTION_CONTEXT  (
  STEP_EXECUTION_ID BIGINT PRIMARY KEY,
  SHORT_CONTEXT VARCHAR(2500) NOT NULL,
  SERIALIZED_CONTEXT CLOB,
  constraint STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID)
  references BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)
) ;

次のリストで各列について説明します。

  • STEP_EXECUTION_ID: コンテキストが属する StepExecution を表す外部キー。特定の実行に複数の行が関連付けられている場合があります。

  • SHORT_CONTEXTSERIALIZED_CONTEXT の文字列バージョン。

  • SERIALIZED_CONTEXT: 直列化されたコンテキスト全体。

アーカイブ

バッチジョブが実行されるたびに複数のテーブルにエントリがあるため、メタデータテーブルのアーカイブ戦略を作成するのが一般的です。テーブル自体は、過去に発生したことの記録を表示するように設計されており、通常、ジョブの実行には影響しませんが、再起動に関するいくつかの顕著な例外があります。

  • フレームワークは、メタデータテーブルを使用して、特定の JobInstance が以前に実行されたかどうかを判断します。ジョブが実行されていて、ジョブが再起動できない場合、例外がスローされます。

  • JobInstance のエントリが正常に完了せずに削除された場合、フレームワークはジョブが再起動ではなく新規であると判断します。

  • ジョブが再開されると、フレームワークは ExecutionContext に永続化されたデータを使用して Job’s 状態を復元します。正常に完了していないジョブのこのテーブルからエントリを削除すると、再度実行した場合に正しいポイントで開始できなくなります。

国際文字およびマルチバイト文字

ビジネス処理でマルチバイト文字セット(中国語やキリル文字など)を使用している場合、それらの文字を Spring Batch スキーマに保持する必要がある場合があります。多くのユーザーは、単にスキーマを変更して VARCHAR 列の長さを 2 倍にするだけで十分であることに気付きます。他の人は、VARCHAR 列の長さの半分の値である max-varchar-length で JobRepository を構成することを好みます。一部のユーザーは、スキーマ定義で VARCHAR の代わりに NVARCHAR を使用することも報告しています。最良の結果は、データベースプラットフォームと、データベースサーバーがローカルに構成されている方法によって異なります。

メタデータテーブルのインデックス作成に関する推奨事項

Spring Batch は、いくつかの一般的なデータベースプラットフォームのコア jar ファイルのメタデータテーブルの DDL サンプルを提供します。インデックス宣言はその DDL には含まれません。これは、正確なプラットフォーム、ローカルの規則、ジョブの運用方法のビジネス要件に応じて、ユーザーがインデックスを作成する方法が多すぎるためです。以下は、Spring Batch が提供する DAO 実装によって WHERE 句でどの列が使用されるか、およびそれらがどのくらいの頻度で使用される可能性があるかを示すものです。

表 1: SQL ステートメント内の Where 句(主キーを除く)と、おおよその使用頻度。

デフォルトのテーブル名

where 句

間隔

BATCH_JOB_INSTANCE

JOB_NAME = ? および JOB_KEY = ?

ジョブが立ち上げられるたびに

BATCH_JOB_EXECUTION

JOB_INSTANCE_ID = ?

ジョブが再開されるたび

BATCH_STEP_EXECUTION

バージョン = ?

コミット間隔で、別名チャンク (そして、ステップの開始時と終了時)

BATCH_STEP_EXECUTION

STEP_NAME = ? および JOB_EXECUTION_ID = ?

各ステップ実行前