Java
MySQL
spring
spring-boot
HikariCP

Spring+HikariCP+MySQLで接続時、SQL実行時のタイムアウトをどう設定するか確認する

やりたいこと

Spring+HikariCP+MySQLで接続時、SQL実行時のタイムアウトをどう設定するか確認する。

環境

動確をとる環境
※"やりたいこと" を確認する環境

Spring関係:5.0.9
HikariCP:2.7.9
MySQL:5.7

DB接続時にタイムアウトさせる

設定する項目(JavaでDataSourceの設定を記述する場合)

HikariDatasourceのインスタンスに対して setConnectionTimeout() で設定する。

@Bean
HikariDataSource datasource() {

    HikariDataSource ds = new HikariDataSource();
    ds.setJdbcUrl("jdbc:mysql://localhost:3306/test?useSSL=false&socketTimeout=10");
    ds.setConnectionTimeout(250); // ★ここ
    ds.setUsername("user");
    ds.setPassword("password");
    return ds;
}

設定する項目(Spring-bootの自動設定を使う場合)

application.propertiesの↓の設定

spring.datasource.hikari.connection-timeout=タイムアウト(ミリ秒)

DB接続後、SQLの結果が返ってこない場合にタイムアウトさせる

JDBCのURLにsocketTimeoutのパラメータをつける。

設定する項目(JavaでDataSourceの設定を記述する場合)

@Bean
HikariDataSource datasource() {

    HikariDataSource ds = new HikariDataSource();
    ds.setJdbcUrl("jdbc:mysql://localhost:3306/test?useSSL=false&socketTimeout=10"); // ★ここ
    ds.setConnectionTimeout(250);
    ds.setUsername("user");
    ds.setPassword("password");
    return ds;
}

設定する項目(Spring-bootの自動設定を使う場合)

spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&socketTimeout=タイムアウト(ミリ秒)

試してみる

windows環境でネットワークの遅延を再現する方法は↓参照。
windowsローカルでネットワーク遅延を再現する方法

サンプルとして書いているコードは、
接続タイムアウト:250ms
接続後の通信タイムアウト:10ms
としているので、下記の手順で想定通り例外が出るのを確認します。

以下、手順。

  1. 接続が確立する前の状態で、ラグを400msにしてSQLの実行を伴う処理を実行すると、出力される例外でタイムアウトが確認できると思います。(接続タイムアウト
  2. 次に、一旦、遅延の発生をstopさせ、SQLの実行を伴う処理を実行(コネクションプールをDB接続させる)します。
  3. その後、ラグを100ms※にして遅延をstartさせ、SQLの実行を伴う処理を実行すると、出力される例外でタイムアウトが確認できると思います。(接続後、SQLが返ってこない場合のタイムアウト
    ※250msを超える値を設定すると接続タイムアウトの設定でタイムアウトしている訳ではないことが確認できなくなるので注意
  4. で、最後にタイムアウトの設定を外すと遅延状態で実行してもタイムアウトしないことを確認しておくと良いと思います。

ただ、、

ログの実行時間見てると、指定したミリ秒通りに例外のログが出ないですよね。
タイムアウトの設定値、遅延の設定値で意図した通りにタイムアウトしてると思うのでタイムアウトの判定自体はできてると思うのですが、、
謎。