我正在尝试在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
}
...
}
我不确定为什么会看到这个异常,因为我已经看到一些基于xml的Spring批处理配置声明了多个数据源。我使用Spring Batch核心版本3.0.1.RELEASE与Spring Boot版本1.1.5.RELEASE。任何帮助将不胜感激。
答案 0 :(得分:19)
您必须提供自己的BatchConfigurer。 Spring不想为你做出决定
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Bean
BatchConfigurer configurer(@Qualifier("batchDataSource") DataSource dataSource){
return new DefaultBatchConfigurer(dataSource);
}
...
答案 1 :(得分:17)
AbstractBatchConfiguration
首先尝试在容器中查找BatchConfigurer
,如果找不到,则尝试自己创建它 - 这是IllegalStateException
被抛出的地方AbstractBatchConfiguration
DefaultBatchConfigurer
3}}容器中的bean。
解决问题的方法是防止在DefaultBatchConfigurer
中创建DataSource
bean。
为此,我们提示使用DefaultBatchConfigurer
注释通过Spring容器创建package batch_config;
...
@EnableBatchProcessing
@ComponentScan(basePackageClasses = MyBatchConfigurer.class)
public class MyBatchConfig {
...
}
:
放置@Component
的配置类我们可以使用@EnableBatchProcessing
进行注释,扫描包含从package batch_config.components;
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.stereotype.Component;
@Component
public class MyBatchConfigurer extends DefaultBatchConfigurer {
}
派生的空类的包:
DataSource
该空派生类的完整代码在这里:
@Configuration
public class BatchTestDatabaseConfig {
@Bean
@Primary
public DataSource dataSource()
{
return .........;
}
}
在此配置中,@ComponentScan
注释适用于@Primary
bean,如下例所示:
DataSource
这适用于Spring Batch版本3.0.3.RELEASE
在@ComponentScan(basePackageClasses = DefaultBatchConfigurer.class)
工作中进行@EnableBatchProcessing
注释的最简单解决方案可能只是添加@Configuration
@EnableBatchProcessing
@ComponentScan(basePackageClasses = DefaultBatchConfigurer.class)
public class MyBatchConfig {
以及{{1}}注释:
{{1}}
答案 2 :(得分:1)
如果我可以添加上述问题,则为每个DS设置2个事务上下文的含义。如何将XA事务与Batch步骤集成,因为我们需要确保步骤级别的TXN管理?要求就像在批处理步骤中我们需要以下内容。
答案 3 :(得分:1)
我想在这里提供一个解决方案,它与@vanarchi回答的解决方案非常相似,但我设法将所有必要的配置放入一个类中。
为了完整起见,此处的解决方案假定主数据源为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", ""});
}
}
此解决方案中的三个关键点:
@EnableBatchProcessing
和@Configuration
进行注释,并从DefaultBatchConfigurer
进行了扩展。通过这样做,我们指示spring-batch在AbstractBatchConfiguration
尝试查找BatchConfigurer
时使用我们的自定义批处理配置器; @Primary
,它指示spring-batch使用此数据源作为存储9个作业相关表的数据源。protected JobRepository createJobRepository() throws Exception
方法,该方法使jobRepository bean使用主数据源,并使用与其他数据源不同的transactionManager实例。答案 4 :(得分:1)
最简单的解决方案是扩展DefaultBatchConfigurer并通过限定符自动连接数据源:
PROD
旁注(因为这也涉及多个数据源的使用):如果使用autoconfig运行数据初始化脚本,则可能会注意到它没有在您期望的数据源上进行初始化。对于该问题,请看以下内容:https://github.com/spring-projects/spring-boot/issues/9528
答案 5 :(得分:0)
首先,创建一个自定义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, ...
}
答案 6 :(得分:0)
您可以在下面的bean中定义并确保您的application.properties文件具有所需的条目
@Configuration
@PropertySource("classpath:application.properties")
public class DataSourceConfig {
@Primary
@Bean(name = "abcDataSource")
@ConfigurationProperties(prefix = "abc.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean(name = "xyzDataSource")
@ConfigurationProperties(prefix = "xyz.datasource")
public DataSource xyzDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
}
application.properties
abc.datasource.jdbc-url=XXXXX
abc.datasource.username=XXXXX
abc.datasource.password=xxxxx
abc.datasource.driver-class-name=org.postgresql.Driver
...........
...........
...........
...........