JobRepository の構成

前述の通りJobRepository は、Spring Batch 内の様々な永続化ドメインオブジェクト(JobExecution や StepExecution など)に対する基本的な CRUD 操作に使用されます。JobOperatorJobStep など、多くの主要なフレームワーク機能で必要とされます。

リソースレス JobRepository の構成

JobRepository インターフェースの最もシンプルな実装は ResourcelessJobRepository です。この実装では、バッチメタデータは使用も保存もされません。これは、再起動が不要で、実行コンテキストが一切関与しないユースケース(実行コンテキストを介してステップ間でデータを共有する場合や、パーティション化されたステップで実行コンテキストを介してマネージャーと ワーカー間でパーティションメタデータを共有する場合など)を対象としています。この実装は、単一のジョブを実行するための最小限の状態(つまり、1 つのジョブインスタンス + 1 つのジョブ実行 + N ステップ実行)を保持します。これは、独自の JVM で実行される 1 回限りのジョブに適しています。このジョブリポジトリは、トランザクションステップだけでなく、非トランザクションステップ(ResourcelessTransactionManager と組み合わせて)でも機能します。

この実装はスレッドセーフではないため、同時実行環境では使用しないでください。

デフォルトでは、@EnableBatchProcessing または DefaultBatchConfiguration を使用する場合、ResourcelessJobRepository が提供されます。

JDBC JobRepository の構成

  • Java

  • XML

@EnableBatchProcessing を使用する場合、ResourcelssJobRepository が提供されます。このセクションでは、ResourcelssJobRepository のカスタマイズ方法について説明します。Spring Batch は、データベースを基盤とする JobRepository インターフェースの実装を 2 つ提供しています。1 つは JDBC 実装(JDBC 準拠のデータベースであればどれでも使用可能)で、もう 1 つは MongoDB 実装です。これらの 2 つの実装は、それぞれ @EnableJdbcJobRepository アノテーションと @EnableMongoJobRepository アノテーションによって提供されます。

次の例は、@EnableJdbcJobRepository アノテーションの属性を使用して JDBC ベースのジョブリポジトリをカスタマイズする方法を示しています。

Java 構成
@Configuration
@EnableBatchProcessing
@EnableJdbcJobRepository(
		dataSourceRef = "batchDataSource",
		transactionManagerRef = "batchTransactionManager",
		tablePrefix = "BATCH_",
		maxVarCharLength = 1000,
		isolationLevelForCreate = "SERIALIZABLE")
public class MyJobConfiguration {

   // job definition

}

ここにリストされている構成オプションはどれも必要ありません。設定されていない場合は、前に示したデフォルトが使用されます。varchar の最大長は、デフォルトで 2500 になります。これは、サンプルスキーマスクリプト内の長い VARCHAR 列の長さです。

バッチ名前空間は、JobRepository 実装とその協力者の実装の詳細の多くを抽象化します。ただし、次の例に示すように、使用可能な構成オプションがまだいくつかあります。

XML 構成
<job-repository id="jobRepository"
    data-source="dataSource"
    transaction-manager="transactionManager"
    isolation-level-for-create="SERIALIZABLE"
    table-prefix="BATCH_"
	max-varchar-length="1000"/>

id 以外には、前述の構成オプションは必要ありません。設定されていない場合は、前に示したデフォルトが使用されます。max-varchar-length のデフォルトは 2500 です。これは、サンプルスキーマスクリプトの長い VARCHAR 列の長さです。

MongoDB JobRepository の設定

JDBC ベースの JobRepository と同様に、MongoDB ベースの JobRepository はバッチメタデータを保存するためにいくつかのコレクションを必要とします。これらのコレクションは、spring-batch-core jar の org/springframework/batch/core/schema-mongodb.jsonl で定義されています。JDBC ベースの JobRepository と同様に、ジョブを実行する前に MongoDB データベースにこれらのコレクションを作成する必要があります。

さらに、MongoDB ドキュメントのフィールド名に . を使用することは推奨されていない (英語) ため、MongoJobRepositoryFactoryBean で使用される MongoTemplate をカスタマイズして、フィールド名内の . を別の文字(例: _)に置き換える必要があります。これは、MongoTemplate で使用される MappingMongoConverter をカスタマイズすることで実現できます。次の例は、Java 構成でこれを行う方法を示しています。

Java 構成
@Bean
public MongoTemplate mongoTemplate(MongoDatabaseFactory mongoDatabaseFactory) {
    MongoTemplate template = new MongoTemplate(mongoDatabaseFactory);
    MappingMongoConverter converter = (MappingMongoConverter) template.getConverter();
    converter.setMapKeyDotReplacement("_");
    return template;
}

JobRepository のトランザクション構成

名前空間または提供された FactoryBean が使用される場合、トランザクションに関するアドバイスがリポジトリの周囲に自動的に作成されます。これは、障害後の再起動に必要な状態を含むバッチメタデータが正しく保持されるようにするためです。リポジトリメソッドがトランザクション対応でない場合、フレームワークの動作は明確に定義されていません。create* メソッド属性の分離レベルは、ジョブの起動時に 2 つのプロセスが同時に同じジョブを起動しようとしても、1 つのみが成功するように個別に指定されます。そのメソッドのデフォルトの分離レベルは SERIALIZABLE で、これは非常に積極的です。通常、READ_COMMITTED も同様に機能します。READ_UNCOMMITTED は、2 つのプロセスがこのように衝突する可能性が低い場合には問題ありません。ただし、create* メソッドの呼び出しは非常に短いため、データベースプラットフォームがサポートしている限り、SERIALIZED が問題を引き起こす可能性はほとんどありません。ただし、この設定をオーバーライドできます。

  • Java

  • XML

次の例は、Java で分離レベルをオーバーライドする方法を示しています。

Java 構成
@Configuration
@EnableBatchProcessing
@EnableJdbcJobRepository(isolationLevelForCreate = "ISOLATION_REPEATABLE_READ")
public class MyJobConfiguration {

   // job definition

}

次の例は、XML の分離レベルをオーバーライドする方法を示しています。

XML 構成
<job-repository id="jobRepository"
                isolation-level-for-create="REPEATABLE_READ" />

名前空間を使用しない場合は、AOP を使用してリポジトリのトランザクション動作も構成する必要があります。

  • Java

  • XML

次の例は、Java でリポジトリのトランザクション動作を構成する方法を示しています。

Java 構成
@Bean
public TransactionProxyFactoryBean baseProxy() {
	TransactionProxyFactoryBean transactionProxyFactoryBean = new TransactionProxyFactoryBean();
	Properties transactionAttributes = new Properties();
	transactionAttributes.setProperty("*", "PROPAGATION_REQUIRED");
	transactionProxyFactoryBean.setTransactionAttributes(transactionAttributes);
	transactionProxyFactoryBean.setTarget(jobRepository());
	transactionProxyFactoryBean.setTransactionManager(transactionManager());
	return transactionProxyFactoryBean;
}

次の例は、XML でリポジトリのトランザクション動作を構成する方法を示しています。

XML 構成
<aop:config>
    <aop:advisor
           pointcut="execution(* org.springframework.batch.core..*Repository+.*(..))"/>
    <advice-ref="txAdvice" />
</aop:config>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*" />
    </tx:attributes>
</tx:advice>

前のフラグメントをほとんど変更せずに、ほぼそのまま使用できます。また、適切な名前空間宣言を含め、spring-tx と spring-aop (または Spring 全体) がクラスパスにあることを確認してください。

テーブルプレフィックスの変更

JobRepository のもう 1 つの変更可能なプロパティは、メタデータテーブルのテーブルプレフィックスです。デフォルトでは、それらはすべて BATCH_ で始まります。BATCH_JOB_EXECUTION と BATCH_STEP_EXECUTION は 2 つの例です。ただし、このプレフィックスを変更する理由が考えられます。スキーマ名をテーブル名の前に追加する必要がある場合、または同じスキーマ内に複数のメタデータテーブルのセットが必要な場合は、テーブルのプレフィックスを変更する必要があります。

  • Java

  • XML

次の例は、Java でテーブルプレフィックスを変更する方法を示しています。

Java 構成
@Configuration
@EnableBatchProcessing
@EnableJdbcJobRepository(tablePrefix = "SYSTEM.TEST_")
public class MyJobConfiguration {

   // job definition

}

次の例は、XML でテーブルプレフィックスを変更する方法を示しています。

XML 構成
<job-repository id="jobRepository"
                table-prefix="SYSTEM.TEST_" />

上記の変更により、メタデータテーブルへのすべてのクエリには SYSTEM.TEST_ というプレフィックスが付きます。BATCH_JOB_EXECUTION は SYSTEM.TEST_JOB_EXECUTION と呼ばれます。

テーブルプレフィックスのみが設定可能です。テーブル名と列名は違います。

リポジトリ内の非標準データベース型

サポートされているプラットフォームのリストにないデータベースプラットフォームを使用する場合、SQL バリアントが十分に近い場合は、サポートされている型のいずれかを使用できる場合があります。これを行うには、名前空間のショートカットの代わりに生の JdbcJobRepositoryFactoryBean を使用し、それを使用してデータベースの種類を最も近いものに設定します。

  • Java

  • XML

次の例は、JdbcJobRepositoryFactoryBean を使用してデータベース型を Java で最も近いものに設定する方法を示しています。

Java 構成
@Bean
public JobRepository jobRepository() throws Exception {
    JdbcJobRepositoryFactoryBean factory = new JdbcJobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setDatabaseType("db2");
    factory.setTransactionManager(transactionManager);
    return factory.getObject();
}

次の例は、JdbcJobRepositoryFactoryBean を使用してデータベース型を XML で最も一致するものに設定する方法を示しています。

XML 構成
<bean id="jobRepository" class="org...JdbcJobRepositoryFactoryBean">
    <property name="databaseType" value="db2"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

データベース型が指定されていない場合、JdbcJobRepositoryFactoryBean は DataSource からデータベース型を自動検出しようとします。プラットフォーム間の主な違いは、主に主キーをインクリメントする戦略によって説明されるため、(Spring Framework の標準実装の 1 つを使用して) incrementerFactory もオーバーライドする必要があることがよくあります。

それでもうまくいかない場合、または RDBMS を使用していない場合、唯一のオプションは、SimpleJobRepository が依存するさまざまな Dao インターフェースを実装し、通常の Spring 方法で手動で接続することです。