1

本番環境で Spring Batch をデプロイしていますが、これはもともとジョブ リポジトリ用の H2 データ ソースを使用して開発されたものです。この最初の取り組みですべてがうまく機能していますが、Spring Batch の使用が拡大するにつれて、H2 をより従来のデータベースに置き換えたいと考えています。良くも悪くも (完全に私の決定ではありませんでした)、代わりに MySQL に移行しています。

ジョブ リポジトリのデータ ソースを H2 から MySQL に切り替え、要素を " classpath:/org/springframework/batch/core/schema-mysql.sql" を使用するように変更しました。初めてバッチ ジョブを実行すると、Spring Batch がリポジトリ テーブルを作成し、問題なくジョブを実行します。

ただし、後続の実行は失敗します...ジョブインクリメンターを適切に使用し、「-next」パラメーターを渡しても、H2で正常に動作することがわかりました。ロギングを「デバッグ」レベルに設定すると、後続の実行で次の例外が発生します。

org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)]; 
Duplicate entry '1' for key 'PRIMARY'; 
nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'

schema-*.sqlSpring Batch がジョブ リポジトリ テーブルを作成するために使用する" " スクリプトを見てきました。他のデータベース タイプ (例: H2、Oracle、Postgres など) は、3 つのシーケンスを作成します... BATCH_STEP_EXECUTION_SEQBATCH_JOB_EXECUTION_SEQ、およびBATCH_JOB_SEQ。私は MySQL の専門家ではありませんが、MySQL はシーケンスをサポートしていないようです... " schema-mysql.sql" には明らかな回避策として次の行が含まれているためです。

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

MySQL のシーケンスと自動インクリメント値の処理が他のデータベースと異なることは明らかであるため、おそらく Spring Batch は、ジョブ リポジトリ テーブルの ID をインクリメントするために別のことを行う必要があります。他に実行する必要がある MySQL 固有の手順はありますか? 前もって感謝します!

4

1 に答える 1

1

問題は、classpath:/org/springframework/batch/core/schema-mysql.sqlジョブを実行するたびにスクリプトを実行していたことです。

jdbc:initialize-databaseH2 ではこれで問題ありません。要素にignore-failures="ALL"属性が 含まれている限り、特に問題はありません。

ただし、シーケンスに対する MySQL 固有の回避策は、Spring Batch が混乱することなく繰り返し実行できるものではありません。

jdbc:initialize-databaseSpring Batch 構成から要素を削除し、そのclasspath:/org/springframework/batch/core/schema-mysql.sqlセットアップ スクリプトを空のデータベースで 1 回手動で実行すると、ジョブは複数の呼び出しを正常に実行します。

于 2013-01-15T21:50:19.173 に答える