Zenn
🌲

JavaのHikariCPでConnectionの状態を確認する方法

2025/03/07に公開

はじめに

HikariCP の Connection Pool を使用してDBアクセスをする際に、取得した Connection が有効かどうかを確認する方法について調査しました。

HikariCPのデフォルト動作

HikariCP は特別な設定をしなくても、コネクションの有効性を自動でチェックする仕組みがあります。
HikariCP では、以下のタイミングで Connection の有効性チェックが行われます。

  1. Connection をプールから取得するとき
    dataSource.getConnection() を呼び出す際、HikariCP は無効な Connection をプールから除外し、常に有効な Connection を返します。
    この際、connectionTestQuery が設定されていなければ、HikariCP は isValid() を自動で使用します。
  2. Connection がアイドル状態のとき
    HikariCP は idleTimeout や keepaliveTime の設定に基づいて、アイドル状態の Connection を定期的にチェックし、無効なものをプールから削除します。
設定 挙動
connectionTestQuery を設定しない JDBC4.0以降なら isValid() を自動で実行してチェック
connectionTestQuery を設定する SELECT 1 などの指定されたクエリを実行してチェック

JDBC4.0以降を使用している場合は、特に何も設定しなくても isValid() による有効性チェックが適用されます。

Connection の有効性を判定する

前述した通り、HikariCP はデフォルトで isValid() を使用した有効性チェックが行われる為、通常は Connection を取得した後で有効性を確認する必要はありませんが、バッチ処理や長時間動作するトランザクションでは、途中でDB接続が切れる可能性があるため、定期的に Connection をチェックしたいケースがあります。
又、クエリを実行中にエラーが発生してリカバリーする際にも、Connection のチェックが有効な場合があります。

Connection の有効性をチェックするには、isValid(int timeout) メソッドを使用します。

import java.sql.Connection;
import java.sql.SQLException;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class TestMain {
    public static void main(String[] args) {
        // HikariCPの設定
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        config.setUsername("username");
        config.setPassword("password");

        // データソースを作成
        HikariDataSource dataSource = new HikariDataSource(config);

        // コネクションを取得
        try (Connection conn = dataSource.getConnection()) {
            if (conn.isValid(2)) {  // 2秒以内に応答があるかチェック
                System.out.println("Connection is valid.");
            } else {
                System.out.println("Connection is invalid.");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        // データソースのクローズ
        dataSource.close();
    }
}

isClosed() では判定できない

isClosed() メソッドでは、Connection がクローズされているかどうかを判定できますが、実際に接続できるかどうかは保証されません。(ネットワークの切断やサーバダウンなどは判定できません)
DBと接続が切れていても、HikariCP がその Connection を認識している場合、false が返る場合があります。
DB接続が有効かどうかを判定するには、isValid() メソッドを使用します。

if (conn.isClosed()) {
    System.out.println("Connection is closed.");
} else {
    System.out.println("Connection is open.");
}

まとめ

HikariCP は、デフォルトで isValid() を使用して Connection の有効性をチェックしているため、通常は connection.isValid() を手動で呼ぶ必要はありませんが、バッチ処理やリカバリーなどを行う場面では、手動で isValid() を使うことが有用な場合があります。

レスキューナウテックブログ

Discussion

ログインするとコメントできます