How to configure multiple connection pools when using multiple data sources in Spring Boot?

I have a Spring Boot application that connects to two separate databases. Everything works fine (I followed the steps described in the documentation and the tutorial ), although I had to manually configure it to configure the JDBC Tomcat connection pool parameters (because when defining multiple data sources, the boot autoconfiguration is ignored and Spring Boot no longer reads tomcat-specific properties , from application.properties).

When I use the debugger while setting up two data sources, I see that both instances of org.apache.tomcat.jdbc.pool.DataSource have the same connection pool in the DataSource.PoolProperties ["name"] record. See the screenshots below in the debugger, each dataSource () method is configured in a separate configuration class. Note that the same connection pool is defined. Primary DataSource CP configuration Secondary DataSource CP configuration

However, from what I see using jConsole + tomcat JMX, there is only one connection pool for which the main database data is configured (URL, credentials, see below). jConsole inspecting the Tomcat JDBC JMX info about the Connection Pool

- Spring . Eclipse Class Decompiler, , Spring, bean-, Spring Boot .

, :

  1. ,
  2. Spring ,

2- , . , -, , Spring, Spring Boot, , , .

+6
3

, . Spring , , .

Spring , , , ( validationQuery validationInterval tomcat CP), .

@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());
    }
}

testDatabaseConnection() Spring

@Query("SELECT 1 FROM MyTable")
public int testConnection();
0

, , . , @user3007501 .

  1. DataSourceBuilder, org.apache.tomcat.jdbc.pool.DataSource. , .

    Hikari Dbcp2, createPooledDataSource() Hikari Dbcp2 Spring DataSourceConfiguration.java. createPooledDataSource() Tomcat.dataSource() .

  2. tomcat datasource application.yml
  3. ., config-name-here.datasource.tomcat ( .tomcat), application.yml, config-name-here.datasource .tomcat
  4. bean- DataSourceProperties
  5. @Qualifier("name of bean from previous step")


application.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


MyCustomDatasourceConfig.java & lt; -

createPooledDataSource() DataSourceConfiguration.java Spring.

import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.beans.factory.annotation.Qualifier;


@Configuration
public class MyCustomDatasourceConfig {
    @Bean(name = "My-First-Data")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.tomcat") 
    // *** NOTE the inclusion of the .tomcat above
    public DataSource primaryDataSource(DataSourceProperties properties) {
        return createPooledDataSource(properties);
    }


    @Bean()
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSourceProperties dataSourcePropsPrimary() {
        return new DataSourceProperties();
    }


    @Bean(name = "My-Second-Data-Source")
    @ConfigurationProperties(prefix = "myotherdatasource.datasource.tomcat") 
    // *** NOTE the inclusion of the .tomcat above
    public DataSource datasourceOtherConfig(@Qualifier("secondary_ds_prop") DataSourceProperties properties) {
        return createPooledDataSource(properties);
    }

    @Bean(name  = "secondary_ds_prop")
    @ConfigurationProperties(prefix = "myotherdatasource.datasource")
    public DataSourceProperties dataSourcePropsSecondary() {
        return new DataSourceProperties();
    }


    private DataSource createPooledDataSource(DataSourceProperties properties) {
        // Using fully qualified path to the tomcat datasource just to be explicit for the sake of this example
        DataSource dataSource = (org.apache.tomcat.jdbc.pool.DataSource)
                   properties.initializeDataSourceBuilder()
                   .type(org.apache.tomcat.jdbc.pool.DataSource.class).build();
        DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(properties.determineUrl());
        String validationQuery = databaseDriver.getValidationQuery();
        if (validationQuery != null) {
            dataSource.setTestOnBorrow(true);
            dataSource.setValidationQuery(validationQuery);
        }
        return dataSource;
    }
}

+2
  1. DataSource JavaEE JDBC, .
    SpringBoot DataSource . Spring.
    , , , - , Hikari, spring.datasource.*. Spring DataSource, .
  2. , DataSource. SpringBoot @ConditionalOnMissingBean , . Spring , , .
    spring-boot-autoconfugire: Spring DataSource, bean- .
    , Bean . Spring DataSource . .
  3. DataSource
+1
source

Source: https://habr.com/ru/post/1684438/


All Articles