如何在Spring Boot中使用多个数据源时设置多个连接池?

And*_*ure 6 java spring tomcat spring-data-jpa spring-boot

我有一个连接到两个独立数据库的Spring Boot应用程序.一切正常(我按照文档中的步骤和教程),虽然为了自定义Tomcat JDBC连接池设置,我不得不手动配置它(因为通过定义多个数据源,引导自动配置被忽略,和Spring Boot不再从application.properties读取特定于tomcat的属性.

当我在配置两个DataSource期间使用调试器时,我看到org.apache.tomcat.jdbc.pool.DataSource实例在DataSource.PoolProperties ["name"]条目中具有相同的连接池.请参阅下面的调试器屏幕截图,每个dataSource()方法都在单独的配置类中配置.请注意,定义了相同的连接池. 主DataSource CP配置 辅助数据源CP配置

然而,从我看到使用JConsole + tomcat的JMX什么,只有一个连接池,其中有主数据库配置的详细信息(URL,证书,见下文). jConsole检查有关连接池的Tomcat JDBC JMX信息

由于Spring内部有多层抽象,我很难调试它.我有Eclipse Class Decompiler插件,我通常用它来查看Spring逻辑,但在这种情况下,数据源的初始化代码在bean注册时发生,而不是在Spring Boot实际使用它们来设置数据时消息来源.

最重要的是,你能帮我理解一下:

  1. 为什么只有一个连接池
  2. 如何使用两个连接池,每个数据源一个
  3. 在Spring代码中查看有关其工作原理的更多详细信息

对于第二个问题,有一个相关的问题,但没有答案.还有一个问题是误报,另一个与Spring有关,而不是Spring Boot,所以请不要将此报告为dupe.

Jam*_*ell 6

这是我必须采取的方法,以便为每个数据源获得单独的池。以下是@user3007501上面提出的要点的实现。

  1. 不要使用DataSourceBuilder,而是创建一个org.apache.tomcat.jdbc.pool.DataSource. 这将创建池并配置连接。

    如果您需要HikariDbcp2替换createPooledDataSource()以下方法的内容,请使用原始 Spring 源DataSourceConfiguration.java 中HikariDbcp2配置部分。下面显示的内容是从链接文件中的方法中窃取的。createPooledDataSource()Tomcat.dataSource()

  2. 添加tomcat在配置部分每个你对你的datasource配置,在您的application.yml
  3. 确保您的配置Bean的每次使用config-name-here.datasource.tomcat(注意.tomcat)属性指定application.yml不会config-name-here.datasource没有.tomcat
  4. 添加 bean 以提供DataSourceProperties每个数据源的配置
  5. 使用@Qualifier("name of bean from previous step")在你的tomcat轮询数据源


应用程序.yml

# Primary Datasource
spring:
  datasource:
    username: your-username-for-ds-1
    password: your-password-for-ds-1
    driver-class-name: net.sourceforge.jtds.jdbc.Driver
    tomcat:
      validation-query: select 1
      test-on-borrow: true


myotherdatasource:
  datasource:
    username: your-username-for-ds-2
    password: your-password-for-ds-2
    driver-class-name: net.sourceforge.jtds.jdbc.Driver
    # HERE: make sure you have a tomcat config for your second datasource like below 
    tomcat:
      validation-query: select 1
      test-on-borrow: true

Run Code Online (Sandbox Code Playgroud)


MyCustomDatasourceConfig.java <- 您的自定义配置文件

createPooledDataSource()是取自DataSourceConfiguration.java在Spring项目源。

# Primary Datasource
spring:
  datasource:
    username: your-username-for-ds-1
    password: your-password-for-ds-1
    driver-class-name: net.sourceforge.jtds.jdbc.Driver
    tomcat:
      validation-query: select 1
      test-on-borrow: true


myotherdatasource:
  datasource:
    username: your-username-for-ds-2
    password: your-password-for-ds-2
    driver-class-name: net.sourceforge.jtds.jdbc.Driver
    # HERE: make sure you have a tomcat config for your second datasource like below 
    tomcat:
      validation-query: select 1
      test-on-borrow: true

Run Code Online (Sandbox Code Playgroud)


And*_*ure 1

我用我当时的做法来回答。如果您找到更好的解决方案或者 Spring 将允许多个连接池,请发布答案,我将选择您的。

因为Spring将根据我在问题中发布的代码配置只有一个连接池(在tomcat CP上设置validationQueryvalidationInterval),所以我添加了一种计划方法来保持第二个数据源的活动。

@Scheduled(fixedRate=INTERVAL_IN_MS)
public void scheduledTestDatabaseConnection() {
    try {
        testDatabaseConnection();
        LOGGER.trace("Tested EJBCA DB connection with success");
    }
    catch (Exception e) {
        LOGGER.error("Got an error when refreshing the EJBCA DB connection '{}'", e.getMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,testDatabaseConnection() 调用 Spring Data Repository 上的方法

@Query("SELECT 1 FROM MyTable")
public int testConnection();
Run Code Online (Sandbox Code Playgroud)