当前位置: 首页 > 知识库问答 >
问题:

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

狄睿
2023-03-14

我有一个Spring Boot应用程序,它连接到两个独立的数据库。虽然为了自定义Tomcat JDBC连接池设置,我必须手动配置它(因为通过定义多个数据源,引导自动配置将被忽略,并且Spring Boot不再从application.properties读取特定于Tomcat的属性),但所有操作都很正常(我遵循了文档和教程中的步骤)。

由于Spring内部的多层抽象,我很难对此进行调试。我有Eclipse类反编译插件,我通常使用它查看Spring逻辑,但在本例中,数据源的初始化代码发生在bean注册时,而不是Spring Boot实际使用它们来设置数据源时。

底线,你能帮我理解一下吗:

  1. 为什么只有一个连接池
  2. 如何使用两个连接池,每个数据源一个
  3. 要查看Spring代码中的哪个位置以获得有关此操作方式的更多详细信息

对于第二个问题,有一个有点相关的问题,但没有答案。还有一个问题是假阳性,还有一个是跟Spring有关的,不是跟Spring靴有关的,所以请不要把这个当成上当。

共有1个答案

傅琦
2023-03-14

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

>

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

    如果需要hikaridbcp2使用原始Spring源datasourceConfiguration.java中的hikaridbcp2配置部分替换下面的createPooleddatasource()方法的内容。以下CreatePooledDataSource()的显示内容是从链接文件中的Tomcat.DataSource()方法中盗取的。


    # 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
    
    
    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;
        }
    }
    
    

  •  类似资料:
    • 我还向b_spring.xml声明了另一个entityManagetFactory、事务管理器和dataSource。 误差 bean初始化失败;嵌套异常是org.springframework.beans.factory.nosuchbeanDefinitionException:没有定义[javax.persistence.entityManagerFactory]类型的唯一bean:预期的单

    • 我的WebApp使用多个数据库,我尝试使用GlassFish连接池来管理连接,但我发现配置示例只使用一个数据库。 那么,我该怎么办?创建与我正在使用的数据库数量相同的连接池,或者是否有方法将一个池配置为多个数据库?

    • 我需要在中为两个设置,目前看来只有一个设置是可能的,您可以选择哪个数据源。

    • 问题内容: 我有一个使用Java Servlet / JSP的应用程序。我的应用有多个客户端,但是每个客户端都有一个单独的数据库。所有数据库都具有相同的架构。我想确定用户登录系统时要使用哪个数据库连接。 例如,客户端A登录后,我确定客户端A属于数据库C,抓住了数据库C的连接,然后继续愉快地进行操作。 我正在将JPA与Hibernate一起用作我的JPA提供程序。是否可以使用多个持久性单元并在登录时

    • 从bugu-mongo 2.11版本开始,支持连接到多个数据库。 在前面的示例代码中,我们都只是连接到一个数据库: //默认的数据库连接 BuguConnection conn = BuguFramework.getInstance().createConnection(); conn.setHost("192.168.0.100"); conn.setPort(27017); conn.setU

    • 问题内容: 我正在编写一个简单的程序,该程序将多个连接连接到不同的服务器以进行状态检查。所有这些连接都是按需构建的;最多可以同时创建10个连接。我不喜欢“每个套接字一个线程”的想法,因此我将所有这些客户端套接字都设置为“非阻塞”,然后将其放入select()池中。 效果很好,直到我的客户抱怨目标服务器停止响应时,等待时间太长才能获得错误报告。 我已经在论坛中检查了几个主题。有人建议可以使用alar