Spring Boot JPA-配置自动重新连接


107

我有一个不错的Spring Boot JPA Web应用程序。它部署在Amazon Beanstalk上,并使用Amazon RDS保留数据。但是,它不经常使用,因此在一段时间后由于以下异常而失败:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:从服务器成功收到的最后一个数据包是79,870,633毫秒之前。
成功发送到服务器的最后一个数据包是79,870,634毫秒之前。大于服务器配置的“ wait_timeout”值。您应考虑在应用程序中使用连接之前使连接有效性到期和/或对其进行测试,或者增加服务器为客户端超时配置的值,或者使用Connector / J连接属性“ autoReconnect = true”来避免此问题。

我不确定如何配置此设置,也无法在http://spring.io(虽然这是一个很好的网站)上找到有关此信息。有什么想法或指向信息的指针?


使用它来打印您的DataSource并验证其属性。stackoverflow.com/a/36586630/148844DataSource如果您@Beans定义了,则Spring Boot不会自动配置DataSourcedocs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/…–
Chloe

Answers:


141

我认为引导正在DataSource为您配置。在这种情况下,由于您使用的是MySQL,因此您最多可以将以下内容添加application.properties到1.3中

spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1

如djxak在注释所指出的,用于四个连接池弹簧引导支撑1.4+定义了特定的名称空间:tomcathikaridbcpdbcp2dbcp被弃用的1.5)。您需要检查使用的连接池,并检查是否支持该功能。上面的示例是针对tomcat的,因此您必须在1.4+中编写如下代码:

spring.datasource.tomcat.testOnBorrow=true 
spring.datasource.tomcat.validationQuery=SELECT 1

请注意,使用的autoReconnect不建议

不建议使用此功能,因为当应用程序无法正确处理SQLExceptions时,它具有与会话状态和数据一致性相关的副作用,并且仅设计用于无法配置应用程序来处理由以下原因导致的SQLExceptions时使用死的和陈旧的连接正确。


8
那是因为我们协调了在文档中编写密钥的方式。我们总是用一个轻松的粘合剂等等都spring.datasource.testOnBorrowspring.datasource.test-on-borrow会工作得很好。查看文档以获取更多详细信息。
Stephane Nicoll 2015年

17
由于它可能会使其他人困惑:SELECT 1确保将连接传递给应用程序之前已经对其进行了测试。通过使用testOnBorrow = true,将在从池中借用对象之前对其进行验证。如果对象验证失败,它将从池中删除,并尝试借用另一个对象。注–为使真值有效,必须将validationQuery参数设置为非空字符串。
里克(Rick)

14
警告!在Spring引导1.4+这被改变:有被定义为四个连接池Spring提供了新的具体的命名空间:tomcathikaridbcpdbcp2。因此,例如,对于tomcat-jdbc连接池,属性应为:spring.datasource.tomcat.testOnBorrow=truespring.datasource.tomcat.validationQuery=SELECT 1
Ruslan Stelmachenko

1
如果我自己配置​​两个不同的数据源,那么如何提供这些配置?我是否需要为两个数据源都提供此配置,例如spring.datasource.mydatasource1.tomcat.testOnBorrow = true spring.datasource.mydatasource1.tomcat.validationQuery = SELECT 1 spring.datasource.mydatasource2.tomcat.testOnBorrow = true spring.datasource。 mydatasource2.tomcat.validationQuery = SELECT 1还是要遵循的其他条件??
Nitish Kumar

2
警告!如果您在应用程序中定义任何DataSource @Bean,那么Spring Boot 将不会配置该池。docs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/… If you define your own DataSource bean, auto-configuration will not occur.我遵循了OAuth2的指南,并且具有@Bean(name = "OAuth") public DataSource secondaryDataSource()...,并且没有进行自动配置或使用testOnBorrow
Chloe

28

以上建议对我没有用。真正有效的是在application.properties中包含以下几行

spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 3600000
spring.datasource.validationQuery = SELECT 1

你可以在这里找到解释


5
您添加的链接显示,如果数据库连接处于非活动状态超过8小时,它将自动关闭,并且会发生上述错误。因此,您的解决方案是不要让连接在更长的时间内保持不活动状态。重新启动后,有什么方法可以连接到SQL Server吗?
Akeshwar Jha

9

spring.datasource.tomcat.testOnBorrow=true在application.properties中设置无效。

像下面这样的编程设置可以正常工作。

import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;    

@Bean
public DataSource dataSource() {
    PoolProperties poolProperties = new PoolProperties();
    poolProperties.setUrl(this.properties.getDatabase().getUrl());         
    poolProperties.setUsername(this.properties.getDatabase().getUsername());            
    poolProperties.setPassword(this.properties.getDatabase().getPassword());

    //here it is
    poolProperties.setTestOnBorrow(true);
    poolProperties.setValidationQuery("SELECT 1");

    return new DataSource(poolProperties);
}

1
如果要声明自定义数据源,则可能是因为您尝试使用spring默认值.tomcat。因此,如果您创建一个自定义Datasource bean,则将@ConfigurationProperties(prefix =“ spring.datasource.tomcat”)添加到DataSource bean,然后它应该允许您在应用程序属性中进行设置。我的示例。.@Bean(name =“ managementDataSource”)@ConfigurationProperties(prefix =“ management.datasource”)public DataSource dataSource(){return DataSourceBuilder.create()。build(); } management.datasource.test-on-borrow = true
贾斯汀

8

我刚刚移到Spring Boot 1.4,发现这些属性已重命名:

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

2
名称是等效的。请参阅Spring Boot文档中有关属性命名的部分。
史蒂芬·哈里森

@StephenHarrison:注意1.4中添加的dbcp。*前缀,在这种情况下,宽松的绑定不适用。
YM

1
@Pawel:取决于您项目中可用的池实现,它可能不是您的dbcp。*属性,请参阅使用SQL进行Spring引导以及相应的Datasource属性
YM 2016年

4

whoami的答案是正确的。使用建议的属性,我无法使其正常工作(使用Spring Boot 1.5.3.RELEASE)

我要添加答案,因为它是完整的配置类,因此它可能对使用Spring Boot的人有所帮助:

@Configuration
@Log4j
public class SwatDataBaseConfig {

    @Value("${swat.decrypt.location}")
    private String fileLocation;

    @Value("${swat.datasource.url}")
    private String dbURL;

    @Value("${swat.datasource.driver-class-name}")
    private String driverName;

    @Value("${swat.datasource.username}")
    private String userName;

    @Value("${swat.datasource.password}")
    private String hashedPassword;

    @Bean
    public DataSource primaryDataSource() {
        PoolProperties poolProperties = new PoolProperties();
        poolProperties.setUrl(dbURL);
        poolProperties.setUsername(userName);
        poolProperties.setPassword(password);
        poolProperties.setDriverClassName(driverName);
        poolProperties.setTestOnBorrow(true);
        poolProperties.setValidationQuery("SELECT 1");
        poolProperties.setValidationInterval(0);
        DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource(poolProperties);
        return ds;
    }
}

您知道为什么需要此自定义代码,以及为什么Spring不会仅从属性文件中读取这些属性吗?我的文件中有几个数据源属性,它可以毫无问题地读取其余所有属性。
长发叔叔

3

我有类似的问题。Spring 4和Tomcat8。我解决了Spring配置问题

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
    <property name="initialSize" value="10" />
    <property name="maxActive" value="25" />
    <property name="maxIdle" value="20" />
    <property name="minIdle" value="10" />
     ...
    <property name="testOnBorrow" value="true" />
    <property name="validationQuery" value="SELECT 1" />
 </bean>

我测试过了 效果很好!这两条线可以完成所有操作,以便重新连接到数据库:

<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />

3

如果有人使用自定义数据源

@Bean(name = "managementDataSource")
@ConfigurationProperties(prefix = "management.datasource")
public DataSource dataSource() {
    return DataSourceBuilder.create().build();
}

属性应如下所示。注意带有前缀的@ConfigurationProperties。前缀是实际属性名称之前的所有内容

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

Spring版本1.4.4.RELEASE的参考


2

正如某些人已经指出的那样,spring-boot 1.4+具有用于四个连接池的特定名称空间。默认情况下,hikaricp在spring-boot 2+中使用。因此,您将必须在此处指定SQL。默认值为SELECT 1。例如,这是您需要的DB2: spring.datasource.hikari.connection-test-query=SELECT current date FROM sysibm.sysdummy1

警告:如果您的驱动程序支持JDBC4,我们强烈建议不要设置此属性。这是针对不支持JDBC4 Connection.isValid()API的“旧版”驱动程序的。这是将在从池中为您提供连接之前执行的查询,以验证与数据库的连接仍然有效。同样,尝试运行不带该属性的池,如果驱动程序不兼容JDBC4,HikariCP将记录错误。默认值:无


0

对于那些想要使用多个数据源从YAML进行操作的人,有一篇很棒的博客文章:https : //springframework.guru/how-to-configure-multiple-data-sources-in-a-spring-boot -应用/

它基本上说您都需要配置数据源属性和数据源,如下所示:

@Bean
@Primary
@ConfigurationProperties("app.datasource.member")
public DataSourceProperties memberDataSourceProperties() {
    return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties("app.datasource.member.hikari")
public DataSource memberDataSource() {
    return memberDataSourceProperties().initializeDataSourceBuilder()
            .type(HikariDataSource.class).build();
}

不要忘记@Primary从其他数据源中删除。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.