メタデータスキーマ

概要

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(32) NOT NULL
);

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

  • 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 ,
	PARAMETER_NAME VARCHAR(100) NOT NULL ,
	PARAMETER_TYPE VARCHAR(100) NOT NULL ,
	PARAMETER_VALUE VARCHAR(2500) ,
	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 テーブルの外部キー。実行ごとに複数の行(つまり、キー / 値のペア)が存在する場合があることに注意してください。

  • PARAMETER_NAME: パラメーター名。

  • PARAMETER_TYPE: パラメーターの型の完全修飾名。

  • PARAMETER_VALUE: パラメーター値

  • 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,
  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 NOT NULL PRIMARY KEY ,
  VERSION BIGINT NOT NULL,
  STEP_NAME VARCHAR(100) NOT NULL,
  JOB_EXECUTION_ID BIGINT NOT NULL,
  CREATE_TIME TIMESTAMP NOT NULL,
  START_TIME TIMESTAMP DEFAULT 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 = ? and JOB_KEY = ?

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

BATCH_JOB_EXECUTION

JOB_INSTANCE_ID = ?

ジョブが再開されるたび

BATCH_STEP_EXECUTION

VERSION = ?

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

BATCH_STEP_EXECUTION

STEP_NAME = ? and JOB_EXECUTION_ID = ?

各ステップ実行前