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

时间:2014-03-27 10:29:58

标签: spring spring-boot configuration

我有一个很好的小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(一个非常好的网站)上找到相关信息。有哪些想法或指示信息?

9 个答案:

答案 0 :(得分:128)

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

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

正如djxak在评论中指出的,1.4 +定义了Spring Boot支持的四个连接池的特定命名空间:tomcathikaridbcpdbcp2({{ 1)}从1.5)开始被弃用。您需要检查您正在使用的连接池,并检查是否支持该功能。上面的示例适用于tomcat,因此您必须在1.4 +:

中按如下方式编写它
dbcp

请注意,spring.datasource.tomcat.testOnBorrow=true spring.datasource.tomcat.validationQuery=SELECT 1 的使用是not recommended

  

不建议使用此功能,因为当应用程序无法正确处理SQLExceptions时,它会产生与会话状态和数据一致性相关的副作用,并且仅在您无法配置应用程序时使用正确处理死亡和陈旧连接导致的SQLExceptions。

答案 1 :(得分:27)

以上建议对我不起作用。 真正有用的是在application.properties

中包含以下行
spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 3600000
spring.datasource.validationQuery = SELECT 1

您可以在here

中找到解释

答案 2 :(得分: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

答案 3 :(得分:7)

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

答案 4 :(得分:3)

我有类似的问题。 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>

我已经测试过了。它运作良好!为了重新连接到数据库,这两行做了所有事情:

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

答案 5 :(得分:2)

whoami's answer是正确的。使用建议的属性我无法使用它(使用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;
    }
}

答案 6 :(得分:1)

如果有人使用自定义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

的参考

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

对于那些希望通过具有多个数据源的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

相关问题