Spring Batch内でいくつかのデータソースを設定しようとしています。起動時に、Spring Batchは次の例外をスローします。
To use the default BatchConfigurer the context must contain no more thanone DataSource, found 2
バッチ構成からのスニペット
@Configuration
@EnableBatchProcessing
public class BatchJobConfiguration {
@Primary
@Bean(name = "baseDatasource")
public DataSource dataSource() {
// first datasource definition here
}
@Bean(name = "secondaryDataSource")
public DataSource dataSource2() {
// second datasource definition here
}
...
}
複数のデータソースを宣言するSpringバッチのxmlベースの構成を見たため、この例外が発生する理由がわかりません。 Spring Bootバージョン1.1.5.RELEASEでSpring Batchコアバージョン3.0.1.RELEASEを使用しています。どんな助けも大歓迎です。
独自のBatchConfigurerを提供する必要があります。春はあなたのためにその決定をしたくない
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Bean
BatchConfigurer configurer(@Qualifier("batchDataSource") DataSource dataSource){
return new DefaultBatchConfigurer(dataSource);
}
...
最も簡単な解決策は、DefaultBatchConfigurerを拡張し、修飾子を介してデータソースを自動接続することです。
@Component
public class MyBatchConfigurer extends DefaultBatchConfigurer {
/**
* Initialize the BatchConfigurer to use the datasource of your choosing
* @param firstDataSource
*/
@Autowired
public MyBatchConfigurer(@Qualifier("firstDataSource") DataSource firstDataSource) {
super(firstDataSource);
}
}
サイドノート(これは複数のデータソースの使用も扱うため):autoconfigを使用してデータ初期化スクリプトを実行する場合、期待するデータソースで初期化されないことに気付くかもしれません。その問題については、これを見てください: https://github.com/spring-projects/spring-boot/issues/9528
ここでソリューションを提供したいと思います。これは@vanarchiが回答したものと非常によく似ていますが、必要なすべての構成を1つのクラスにまとめることができました。
完全を期すために、ここでのソリューションはプライマリデータソースがhsqlであると仮定しています。
_@Configuration
@EnableBatchProcessing
public class BatchConfiguration extends DefaultBatchConfigurer {
@Bean
@Primary
public DataSource batchDataSource() {
// no need shutdown, EmbeddedDatabaseFactoryBean will take care of this
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
EmbeddedDatabase embeddedDatabase = builder
.addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql")
.setType(EmbeddedDatabaseType.HSQL) //.H2 or .DERBY
.build();
return embeddedDatabase;
}
@Override
protected JobRepository createJobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(batchDataSource());
factory.setTransactionManager(transactionManager());
factory.afterPropertiesSet();
return (JobRepository) factory.getObject();
}
private ResourcelessTransactionManager transactionManager() {
return new ResourcelessTransactionManager();
}
//NOTE: the code below is just to provide developer an easy way to access the in-momery hsql datasource, as we configured it to the primary datasource to store batch job related data. Default username : sa, password : ''
@PostConstruct
public void getDbManager(){
DatabaseManagerSwing.main(
new String[] { "--url", "jdbc:hsqldb:mem:testdb", "--user", "sa", "--password", ""});
}
_
}
このソリューションの3つのキーポイント:
@EnableBatchProcessing
_および_@Configuration
_の注釈が付けられ、DefaultBatchConfigurer
から拡張されます。これを行うことで、AbstractBatchConfiguration
がBatchConfigurer
を検索しようとするときに、カスタマイズされたバッチ構成を使用するようにspring-batchに指示します。@Primary
_として注釈を付けます。これは、9つのジョブ関連テーブルを格納するデータソースとしてこのデータソースを使用するようにspring-batchに指示します。protected JobRepository createJobRepository() throws Exception
メソッドをオーバーライドします。これにより、jobRepository Beanはプライマリデータソースを使用し、他のデータソースとは異なるtransactionManagerインスタンスを使用します。上記の質問に追加する場合、DSごとに1つのトランザクションコンテキストを2つ持つことの意味。ステップレベルでTXN管理を確保する必要があるため、XAトランザクションをバッチステップに統合する方法要件は、次が必要なバッチステップのようなものです。
最初に、カスタムBatchConfigurerを作成します
@Configuration
@Component
public class TwoDataSourcesBatchConfigurer implements BatchConfigurer {
@Autowired
@Qualifier("dataSource1")
DataSource dataSource;
@Override
public JobExplorer getJobExplorer() throws Exception {
...
}
@Override
public JobLauncher getJobLauncher() throws Exception {
...
}
@Override
public JobRepository getJobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
// use the autowired data source
factory.setDataSource(dataSource);
factory.setTransactionManager(getTransactionManager());
factory.afterPropertiesSet();
return factory.getObject();
}
@Override
public PlatformTransactionManager getTransactionManager() throws Exception {
...
}
}
その後、
@Configuration
@EnableBatchProcessing
@ComponentScan("package")
public class JobConfig {
// define job, step, ...
}