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


106

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/148844 Spring BootはDataSource@Beansを定義している場合、自動構成しませんDataSourcedocs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/...
クロエ

回答:


140

ブートがを構成しているDataSourceと思います。この場合、MySQLを使用してapplication.propertiesいるため、最大1.3に以下を追加できます。

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

djxakコメントで述べたように、4つの接続プール春のブートサポートのため1.4+定義の特定の名前空間は:tomcathikaridbcpdbcp2dbcp1.5のよう推奨されていません)。使用している接続プールを確認し、その機能がサポートされているかどうかを確認する必要があります。上記の例はtomcatのためのものなので、1.4以降では次のように記述する必要があります。

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

の使用autoReconnect推奨されないことに注意してください。

この機能の使用はお勧めしません。アプリケーションがSQLExceptionを適切に処理しない場合、セッション状態とデータの一貫性に関連する副作用があり、アプリケーションがSQLExceptionを処理するように構成できない場合にのみ使用するように設計されています。デッドおよび古くなった接続を適切に。


8
これは、ドキュメントでのキーの記述方法を統一したためです。私たちは、常に使用、リラックスの両方ので、バインダーをspring.datasource.testOnBorrowし、spring.datasource.test-on-borrowうまく動作します。詳細については、ドキュメントを確認しください。
ステファンニコル2015

17
他を混乱させる可能性があるためSELECT 1、アプリケーションに渡される前に接続がテストされていることを保証します。を使用するtestOnBorrow = trueと、オブジェクトはプールから借用される前に検証されます。オブジェクトが検証に失敗した場合、そのオブジェクトはプールから削除され、別のオブジェクトの借用を試みます。注– true値が効果を発揮するには、validationQueryパラメータをnull以外の文字列に設定する必要があります。
リック

14
警告!春ブーツで1.4+これはされた変更:4つの接続プールスプリング支援のための新たな特定の名前空間が定義されました:tomcathikaridbcpdbcp2。したがって、たとえば、tomcat-jdbc接続プールの場合、プロパティは次のようにspring.datasource.tomcat.testOnBorrow=trueなりspring.datasource.tomcat.validationQuery=SELECT 1ます。
Ruslan Stelmachenko 2017年

1
私が2つの異なるデータソースを構成している場合、これらの構成を提供するにはどうすればよいですか?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 2017

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
クロエ、

28

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

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

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


5
追加したリンクは、データベース接続が8時間以上アクティブでない場合、自動的に閉じられ、上記のエラーが発生することを示しています。したがって、あなたの解決策は、接続が長期間にわたって非アクティブのままになることを防ぐことではありません。再起動後にSQLサーバーに接続する方法はありますか?
Akeshwar Jha 2017

9

spring.datasource.tomcat.testOnBorrow=trueapplication.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
Justin

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 docsのプロパティの命名に関するセクションを参照してください。
スティーブンハリソン

@StephenHarrison:1.4で追加されたdbcp。*接頭辞に注意してください。この場合、リラックスしたバインディングは適用されません。
YM

1
@Pawel:プロジェクトで使用可能なプール実装によっては、dbcp。*プロパティではない場合があります。SQLを使用したSpringブートおよび対応するDatasourceプロパティを参照してください。
YM

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>

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

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

3

誰かがカスタム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のリファレンス


2

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

複数のデータソースを持つ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他のデータソースから削除することを忘れないでください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.