web-dev-qa-db-ja.com

Spring Boot JPA-自動再接続の構成

素敵な小さな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 (ただし、非常に良いサイト)で情報を見つけることができません。情報へのアイデアや指針は何ですか?

98
stoffer

ブートがDataSourceを設定していると思います。この場合、MySQLを使用しているため、次のapplication.propertiesを1.3まで追加できます。

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

Djxakがコメントで指摘したように、1.4 +はSpring Bootがサポートする4つの接続プールの特定の名前空間を定義します:Tomcathikaridbcpdbcp2dbcp 1.5)で非推奨になりました。使用している接続プールを確認し、その機能がサポートされているかどうかを確認する必要があります。上記の例はTomcat用であるため、1.4 +では次のように記述する必要があります。

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

autoReconnectの使用は 非推奨 であることに注意してください。

この機能の使用は、アプリケーションがSQLExceptionsを適切に処理しない場合にセッション状態とデータの一貫性に関連する副作用があり、アプリケーションを構成してSQLExceptionsデッドおよび古い接続を適切に。

131
Stephane Nicoll

上記の提案は私にはうまくいきませんでした。実際に機能したのは、application.propertiesに次の行を含めることです

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

あなたは説明を見つけることができます こちら

27
Soumya

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
8
Jose Jurado

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

同様の問題があります。 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>

私はテストしました。うまくいきます!この2行は、データベースに再接続するためにすべてを実行します。

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

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;
    }
}
2
naoru

誰かがカスタム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バージョン1.4.4.RELEASEのリファレンス

1
Justin

一部の人々がすでに指摘したように、spring-boot 1.4+には、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
code4kix