我使用Spring启动创建了一个Spring批处理应用程序,我有一个Job
,包含9个步骤。这些步骤使用DataSource
,我在配置文件中创建了它的bean,如下所示:
@Configuration
public class DatabaseConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
@Primary
public DataSource dataSource(){
return DataSourceBuilder.create().build();
}
}
此DataSource
正在使用application.yml
文件中声明的属性:
spring:
datasource:
url: jdbc:mysql://localhost:3306/db_01?zeroDateTimeBehavior=convertToNull
username: xxxx
password: ****
到目前为止,所有工作都符合预期。
我想要做的是,我在第5个数据库(db_settings)中参数化了4个数据库,我使用SQL查询进行选择。此查询将返回4个数据库及其用户名和密码,如下所示:
+--------+-----------------------------------+-----------------+-----------------+
| id | url | username_db | password_db |
+--------+-----------------------------------+-----------------+-----------------+
| 243 | jdbc:mysql://localhost:3306/db_01 | xxxx | **** |
| 244 | jdbc:mysql://localhost:3306/db_02 | xxxx | **** |
| 245 | jdbc:mysql://localhost:3306/db_03 | xxxx | **** |
| 247 | jdbc:mysql://localhost:3306/db_04 | xxxx | **** |
+--------+-----------------------------------+-----------------+-----------------+
因此,我想在所有4个数据库上运行它们,而不是使用'application.yml'中声明的数据库来运行这些步骤。 考虑到处理的卷,有必要能够并行地在这些数据库上启动批处理。
有谁知道如何实现这个?
答案 0 :(得分:1)
赏金在哪里? : - )
感谢KeatsPeeks,AbstractRoutingDataSource
是解决方案的良好开端,这部分是good tutorial。
主要是重要的部分是:
public class MyRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
String language = LocaleContextHolder.getLocale().getLanguage();
System.out.println("Language obtained: "+ language);
return language;
}
}
注册多个数据源
<bean id="abstractDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="concreteDataSourceOne"
parent="abstractDataSource"
p:url="${jdbc.databaseurlOne}"/>
<bean id="concreteDataSourceTwo"
parent="abstractDataSource"
p:url="${jdbc.databaseurlTwo}"/>
之后,问题就变成了:
如何在春季启动时加载数据源配置属性,并使用数据库中的配置属性配置相应的dataSource
。
如何在春季批次中使用多个dataSource
如何根据弹簧批处理作业(步骤)定义查找代码
通常这应该是一个业务点,您需要定义查找策略,并且可以注入com.example.demo.datasource.CustomRoutingDataSource#determineCurrentLookupKey
以路由到专用数据源。
真正有趣的是它实际上支持多个dataSource
,但数据库设置确实无法存储在数据库中。原因是它会产生循环依赖性问题:
The dependencies of some of the beans in the application context form a cycle:
batchConfiguration (field private org.springframework.batch.core.configuration.annotation.JobBuilderFactory com.example.demo.batch.BatchConfiguration.jobs)
↓
org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration (field private java.util.Collection org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration.dataSources)
┌─────┐
| routingDataSource defined in class path resource [com/example/demo/datasource/DataSourceConfiguration.class]
↑ ↓
| targetDataSources defined in class path resource [com/example/demo/datasource/DataSourceConfiguration.class]
↑ ↓
| myBatchConfigurer (field private java.util.Collection org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration.dataSources)
└─────┘
显然,解决方案是打破dataSource
和routingDataSource
dataSource
https://scattercode.co.uk/2013/11/18/spring-data-multiple-databases/ https://numberformat.wordpress.com/2013/12/27/hello-world-with-spring-batch-3-0-x-with-pure-annotations/
http://spring.io/guides/gs/batch-processing/
Github获取代码。