Spring Boot JPA - configuring auto reconnect

I have a nice little Spring Boot JPA web application. It is deployed on Amazon Beanstalk and uses an Amazon RDS for persisting data. It is however not used that often and therefore fails after a while with this kind of exception:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 79,870,633 milliseconds ago.
The last packet sent successfully to the server was 79,870,634 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

I am not sure how to configure this setting and can not find information on it on http://spring.io (a very good site though). What are some ideas or pointers to information?

156964 次浏览

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

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

正如 djxak 在评论中指出的,1.4 + 为 Spring Boot 支持的四个连接池定义了特定的名称空间: tomcathikaridbcpdbcp2(从1.5开始不推荐使用 dbcp)。您需要检查正在使用的连接池,并检查该特性是否受支持。上面的例子是用于 tomcat 的,因此您必须按照1.4 + 中的方式编写它:

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

Note that the use of autoReconnect is 不推荐:

不推荐使用此特性,因为当应用程序不能正确处理 SQLException 时,它会产生与会话状态和数据一致性相关的副作用,并且只有当您无法配置应用程序以正确处理死亡和过期连接导致的 SQLException 时才会使用此特性。

我也有类似的问题。 Spring 4和 Tomcat 8。我用 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>

I have tested. It works well! This two line does everything in order to reconnect to database:

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

The above suggestions did not work for me. 真正起作用的是在 application.properties 中包含以下代码行

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

你可以从 给你中找到解释

我刚刚转到 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

在 application.properties 中设置 spring.datasource.tomcat.testOnBorrow=true不起作用。

像下面这样的编程设置没有任何问题。

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

以防有人使用自定义 DataSource

@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 Version 1.4.4. RELEASE 的参考

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

警告 : 如果您的驱动程序支持 JDBC4,我们强烈建议不要设置此属性。这是针对不支持 JDBC4 Connection.isValid () API 的“遗留”驱动程序的。这是在从池中向您提供连接以验证到数据库的连接是否仍然存在之前执行的查询。再次尝试不使用此属性运行池,如果您的驱动程序不符合 JDBC4,HikariCP 将记录一个错误。默认值: 没有

对于那些希望从 YAML 进行多数据源操作的人来说,有一篇很棒的博客文章是关于它的: https://springframework.guru/how-to-configure-multiple-data-sources-in-a-spring-boot-application/

它基本上是说,您都需要像下面这样配置数据源属性和数据源:

@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