Spring Boot 使用 JdbcTemplate 和多个数据源自动重新连接到 PostgreSQL

Posted

技术标签:

【中文标题】Spring Boot 使用 JdbcTemplate 和多个数据源自动重新连接到 PostgreSQL【英文标题】:Spring Boot auto reconnect to PostgreSQL using JdbcTemplate and multiple datasources 【发布时间】:2017-09-12 17:21:57 【问题描述】:

我有一个使用 PostgreSQL 9.6 作为数据源的 Spring Boot v 1.5.1.RELEASE 应用程序。即使在空闲时,我的应用程序仍然连接到 Postgres,但如果连接丢失,则应用程序不会重新连接而是抛出:

org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is org.postgresql.util.PSQLException: This connection has been closed.
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:342) ~[spring-jdbc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:366) ~[spring-jdbc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:212) ~[spring-jdbc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.java:134) [spring-jdbc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.java:97) [spring-jdbc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99) [spring-jdbc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649) [spring-jdbc-4.3.6.RELEASE.jar:4.3.6.RELEASE]

虽然我没有使用 JPA,而且我相信我使用的是 spring-boot-starter 附带的 Tomcat 池,但我已经阅读并尝试了讨论的建议 here 和 here,但没有运气。在我的属性文件中,我尝试过:

#spring.datasource.tomcat.test-on-borrow=true
#spring.datasource.tomcat.validation-query=SELECT 1

#spring.datasource.tomcat.test-while-idle=true
#spring.datasource.tomcat.time-between-eviction-runs-millis=3600000
#spring.datasource.tomcat.validation-query=SELECT 1

#spring.datasource.dbcp2.test-on-borrow=true
#spring.datasource.dbcp2.validation-query=SELECT 1

spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1

但是,我使用了两个数据源,配置如下:

@Configuration
public class DatabaseConfiguration 

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.ds_pgsql_rtmain")
    public DataSource rtmainDataSource() 
    
        DataSource dataSource = DataSourceBuilder.create().build();
        return dataSource;
    

    @Bean
    @ConfigurationProperties(prefix = "spring.ds_pgsql_pdns")
    public DataSource pdnsDataSource() 
    
        return DataSourceBuilder.create().build();
    

    @Bean
    @Primary
    public JdbcTemplate rtmainJdbcTemplate(DataSource rtmainDataSource) 
    
        return new JdbcTemplate(rtmainDataSource);
    

    @Bean
    public JdbcTemplate pdnsJdbcTemplate(@Qualifier("pdnsDataSource") DataSource pdnsDataSource) 
        return new JdbcTemplate(pdnsDataSource);
       


我不确定问题是我没有正确配置数据池还是因为我手动配置数据源时池不起作用。或者是其他东西。非常感谢您的帮助,谢谢。

【问题讨论】:

【参考方案1】:

是的,因为您没有使用自动配置的数据源,所以它不起作用。

由于您从自己的前缀应用属性,您只需将test-on-borrowvalidation-query 放在您自己的前缀上。试试这个:

spring.ds_pgsql_rtmain.test-on-borrow=true
spring.ds_pgsql_rtmain.validation-query=SELECT 1

spring.ds_pgsql_pdns.test-on-borrow=true
spring.ds_pgsql_pdns.validation-query=SELECT 1

【讨论】:

以上是关于Spring Boot 使用 JdbcTemplate 和多个数据源自动重新连接到 PostgreSQL的主要内容,如果未能解决你的问题,请参考以下文章

#私藏项目实操分享#专为初学者打造—Spring框架学习笔记

spring boot系列spring boot 使用mongodb

使用 spring-boot:run 时是不是可以使用 spring-boot 命令行属性?

spring boot 2.0之使用spring boot

spring boot8.spring boot的日志框架使用

(转)Spring Boot 2 :使用 Docker 部署 Spring Boot