在多个数据库上并行运行Spring批处理

时间:2017-06-08 11:39:25

标签: spring spring-boot spring-batch

我使用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'中声明的数据库来运行这些步骤。 考虑到处理的卷,有必要能够并行地在这些数据库上启动批处理。

有谁知道如何实现这个?

1 个答案:

答案 0 :(得分:1)

赏金在哪里? : - )

感谢KeatsPeeks,AbstractRoutingDataSource是解决方案的良好开端,这部分是good tutorial

主要是重要的部分是:

  1. 定义查找代码
  2. public class MyRoutingDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { String language = LocaleContextHolder.getLocale().getLanguage(); System.out.println("Language obtained: "+ language); return language; } }

    1. 注册多个数据源

                                                                            

      <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}"/>
      
    2. 之后,问题就变成了:

      1. 如何在春季启动时加载数据源配置属性,并使用数据库中的配置属性配置相应的dataSource

      2. 如何在春季批次中使用多个dataSource

        实际上当我尝试谷歌时,似乎这是最常见的情况,谷歌给出了建议搜索词 - “春季批量多个数据源”,有很多文章,所以我选择了答案

      3. 如何根据弹簧批处理作业(步骤)定义查找代码

        通常这应该是一个业务点,您需要定义查找策略,并且可以注入com.example.demo.datasource.CustomRoutingDataSource#determineCurrentLookupKey以路由到专用数据源。

      4. 限制

        真正有趣的是它实际上支持多个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)
        └─────┘
        

        显然,解决方案是打破dataSourceroutingDataSource

        之间的依赖关系
        • 在属性
        • 中保存数据库设置
        • 或涉及其他方法但不包括在主要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/

        How to java-configure separate datasources for spring batch data and business data? Should I even do it?

        Github获取代码。