【问题标题】:Hikari CP properties are not working with Multiple datasource configuration in Spring 1.5.18Hikari CP 属性不适用于 Spring 1.5.18 中的多数据源配置
【发布时间】:2019-09-03 23:55:08
【问题描述】:

我们在 Spring Boot 应用程序中使用了多个数据源配置。两个数据源都只属于 mysql。

使用以下方式配置多个数据源:

https://medium.com/@joeclever/using-multiple-datasources-with-spring-boot-and-spring-data-6430b00c02e7

pom.xml 更改:

<!-- exclude tomcat jdbc connection pool, use HikariCP -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- exclude tomcat-jdbc, Spring Boot will use HikariCP automatically -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
</dependency>

.properties:

spring.db1.datasource.jdbcUrl=jdbc:mysql://localhost:3306/db1?zeroDateTimeBehavior=convertToNull
spring.db1.datasource.driverClassName=com.mysql.jdbc.Driver
spring.db1.datasource.username=root
spring.db1.datasource.password=
spring.db1.datasource.hikari.maximum-pool-size=5
spring.db1.datasource.hikari.minimum-idle=1

spring.db2.datasource.jdbcUrl=jdbc:mysql://localhost:3306/db2?zeroDateTimeBehavior=convertToNull
spring.db2.datasource.driverClassName=com.mysql.jdbc.Driver
spring.db2.datasource.username=root
spring.db2.datasource.password=
spring.db2.datasource.hikari.maximum-pool-size=5
spring.db2.datasource.hikari.minimum-idle=1

数据源 Bean 配置:

@Bean
@ConfigurationProperties(prefix = "spring.db1.datasource")
public DataSource db1DataSource() {
    return DataSourceBuilder.create().build();
}


@Bean
@ConfigurationProperties(prefix = "spring.db2.datasource")
public DataSource db2Source() {
    return DataSourceBuilder.create().build();
}   

当我启动应用程序时,它默认创建 10 个 db1(@Primary 数据源)连接,但它没有考虑最大池大小和最小空闲属性。 它也没有为 db2 创建连接。

是否遗漏了任何配置?请帮忙

【问题讨论】:

    标签: spring-boot spring-data-jpa hikaricp


    【解决方案1】:

    确保你有@Primary

    @Primary
    @Bean
    @ConfigurationProperties(prefix = "spring.db1.datasource")
    public DataSource db1DataSource() {
        return DataSourceBuilder.create().build();
    }
    
    
    @Bean
    @ConfigurationProperties(prefix = "spring.db2.datasource")
    public DataSource db2Source() {
        return DataSourceBuilder.create().build();
    } 
    

    根据https://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html可以定义如下属性

    spring.db1.datasource.jdbcUrl=jdbc:mysql://localhost:3306/db1?zeroDateTimeBehavior=convertToNull
    spring.db1.datasource.username=root
    spring.db1.datasource.password=
    spring.db1.datasource.maximum-pool-size=5
    spring.db1.datasource.minimumIdle=1
    
    spring.db2.datasource.jdbcUrl=jdbc:mysql://localhost:3306/db2?zeroDateTimeBehavior=convertToNull
    spring.db2.datasource.username=root
    spring.db2.datasource.password=
    spring.db2.datasource.maximum-pool-size=5
    spring.db2.datasource.minimumIdle=1
    

    同样使用 DataSourceBuilder 可以根据连接字符串自动检测驱动程序。 你可以定义logging.level.com.zaxxer.hikari.HikariConfig=TRACE 查看您的连接属性是否正常工作。

    【讨论】:

    • 是的,我已经提到了@Primary,但没有工作。您提供的属性适用于当前版本,而不适用于 1.5.18
    • 我在HikariConfig 中没有看到任何关于 TRACE 级别的日志语句。但 DEBUG 应该足以记录配置属性。
    【解决方案2】:

    看看我的解决方案:https://github.com/dijalmasilva/spring-boot-multitenancy-datasource-liquibase

    使用此解决方案,您可以在以后添加更多数据源而无需更改代码!

    【讨论】:

      【解决方案3】:

      我遇到了一个类似的问题,即非主数据库没有连接。

      最后我做了以下更改并且它起作用了- 您可以在下定义您的池大小和其他参数 特定数据库配置的 DataSourceProperties。

      首先请检查你的包结构-

      com.example.product.entity.db1

      com.example.product.entity.db2

      com.example.product.repository.db1

      com.example.product.repository.db2

      com.example.product.configuration

      DB1 配置

      DB2 配置

      @Configuration
      @EnableTransactionManagement
      @EnableJpaRepositories(
          entityManagerFactoryRef = "db1EntityManagerFactory",
          transactionManagerRef="db1TransactionManager",
          basePackages="com.example.product.repository.db1"
              )
      public class DB1Configuration 
      {
      
          @Bean(name = "db1DataSourceProperties")
          @Primary
          @ConfigurationProperties("spring.datasource")
          public DataSourceProperties db1DataSourceProperties() {
              return new DataSourceProperties();
          }
      
          @Primary
          @Bean(name = "db1DataSource")
          public DataSource db1DataSource()
          {
              return db1DataSourceProperties().
                      initializeDataSourceBuilder().
                      type(HikariDataSource.class).build();
      
          }
      
      
          @Primary
          @Bean(name = "db1EntityManagerFactory")
          public LocalContainerEntityManagerFactoryBean 
          entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("db1DataSource")DataSource dataSource){
      
              return builder.dataSource(dataSource)
                            .packages("com.example.product.entity.db1").
                            persistenceUnit("db1").build();
          }
      
          @Primary
          @Bean(name="db1TransactionManager")
          public PlatformTransactionManager reconTransactionManager(@Qualifier("db1EntityManagerFactory")EntityManagerFactory reconEntityManagerFactory)
          {
              return new JpaTransactionManager(db1EntityManagerFactory);
          }
      
      
      
      }
      
      
      
      
      
      
      
      
      import javax.persistence.EntityManagerFactory;
      import javax.sql.DataSource;
      
      import org.apache.commons.dbcp.BasicDataSource;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
      import org.springframework.boot.context.properties.ConfigurationProperties;
      import org.springframework.boot.jdbc.DataSourceBuilder;
      import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
      import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder.Builder;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
      import org.springframework.orm.jpa.JpaTransactionManager;
      import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
      import org.springframework.transaction.PlatformTransactionManager;
      import org.springframework.transaction.annotation.EnableTransactionManagement;
      
      @Configuration
      @EnableTransactionManagement
      @EnableJpaRepositories(
          entityManagerFactoryRef = "db2EntityManagerFactory",
          transactionManagerRef ="db2TransactionManager",
          basePackages={"com.exmaple.product.repository.db2"}
              )
      public class DB2Configuration 
      {
          @Bean(name = "db2DataSourceProperties")
          @ConfigurationProperties("db2.datasource")
          public DataSourceProperties db2DataSourceProperties() {
              return new DataSourceProperties();
          }
      
      
          @Bean(name = "db2DataSource")
          public DataSource db2DataSource()
          {
              return db2DataSourceProperties().
                      initializeDataSourceBuilder().
                      type(BasicDataSource.class).build();
      
          }
      
      
          @Bean(name = "db2EntityManagerFactory")
          public LocalContainerEntityManagerFactoryBean 
          itmsEntityManagerFactory(final EntityManagerFactoryBuilder builder)
          {
      
            Builder dataSource = builder.dataSource(db2DataSource());
          return dataSource.
            packages("com.example.product.entity.db2").persistenceUnit("db2").build();
      
          }
      
      
          @Bean(name = "db2TransactionManager")
          public PlatformTransactionManager itmsTransactionManager(@Qualifier("db2EntityManagerFactory")EntityManagerFactory db2EntityManagerFactory)
          {
              return new JpaTransactionManager(db2EntityManagerFactory);
          }
      }
      
      
      application.properties
      spring.datasource.driver = com.mysql.cj.jdbc.Driver
      spring.datasource.url= jdbc:mysql://localhost:3306/db1
      spring.datasource.username=root
      spring.datasource.password=root
      
      db2.datasource.driver=com.mysql.cj.jdbc.Driver
      db2.datasource.url=jdbc:mysql://localhost:3306/db2
      db2.datasource.username=root
      db2.datasource.password=root
      
      
      

      【讨论】:

        最近更新 更多