Spring BatchでJob内で利用するデータベースとJobを管理するデータベースを別々にする方法は、Spring Bootのドキュメントに書かれているのですが、実装例がないのでメモしておきます。
Spring Boot 3.4, Spring Batch 5.2で動作確認しました。
次のようなConfigクラスを用意しておけば良いです。
package com.example.batch;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.batch.BatchDataSource;
import org.springframework.boot.autoconfigure.batch.BatchTransactionManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.support.JdbcTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.batch.datasource.url")
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource")
public DataSourceProperties defaultDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("spring.datasource.hikari")
public HikariDataSource defaultDataSource(
@Qualifier("defaultDataSourceProperties") DataSourceProperties properties) {
HikariDataSource dataSource = properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
dataSource.setPoolName("default-pool");
return dataSource;
}
@Bean
@ConfigurationProperties("spring.batch.datasource")
public DataSourceProperties batchDataSourceProperties() {
return new DataSourceProperties();
}
@BatchDataSource
@Bean(defaultCandidate = false)
@ConfigurationProperties("spring.batch.datasource.hikari")
public HikariDataSource batchDataSource(@Qualifier("batchDataSourceProperties") DataSourceProperties properties) {
HikariDataSource dataSource = properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
dataSource.setPoolName("batch-pool");
return dataSource;
}
@BatchTransactionManager
@Bean(defaultCandidate = false)
public PlatformTransactionManager batchTransactionManager(@BatchDataSource DataSource dataSource) {
return new JdbcTransactionManager(dataSource);
}
}
@Bean(defaultCandidate = false)をつけることによって@Qualifier(@BatchDataSourceや@BatchTransactionManagerを含む)で明示しない限り、インジェクションの対象となりません。
Spring BootのAuto Configurationでは、JobRepository、JobExplorerを作成する際に@BatchDataSourceや@BatchTransactionManagerアノテーションが付いたBean定義があればそちらを使うようになっています。
プロパティの設定例は次のとおりです。
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/mydatabase
spring.datasource.username=myuser
spring.datasource.password=secret
spring.batch.datasource.driver-class-name=org.postgresql.Driver
spring.batch.datasource.url=jdbc:postgresql://localhost:15432/spring_batch
spring.batch.datasource.username=spring_batch
spring.batch.datasource.password=admin
spring.datasource.*にJob内で利用するデータベースを設定します。これは通常のデータベースの設定と同じプロパティを使うようにしました。spring.batch.datasource.*にJobを管理するデータベースを設定します。@ConditionalOnProperty(name = "spring.batch.datasource.url")がついているため、spring.batch.datasource.urlでJobを管理するデータベースの設定を明示的に行った時のみ上記のConfigが有効になります。spring.batch.datasource.urlの指定がない場合はデフォルトのAuto Configurationのままです。
この例では、Job内で利用するデータベースとJobを管理するデータベースの両方にPostgreSQLを使用していますが、別のデータベースでも構いません。
例えば、次のような定義にすれば、Jobを管理するデータベースにインメモリのH2データベースを利用できます。
spring.batch.datasource.url=jdbc:h2:mem:spring_batch
spring.batch.datasource.driverClassName=org.h2.Driver
spring.batch.datasource.username=sa
spring.batch.datasource.password=