MySQLのConnector/J (JDBC)にはconnectTimeoutとsocketTimeoutのパラメータがあり、JDBCの接続文字列に追加することで設定できる。
設定例
値はどちらもミリ秒で設定できる。
どちらも30秒で設定する場合、下記のようになる。
jdbc:mysql://localhost:3306/sample?connectTimeout=30000&socketTimeout=30000
socketTimeoutの注意事項
socketTimeoutはアプリケーションからMySQLの応答が設定値を超えて待機すると、java.net.SocketTimeoutException
に類する例外が発生するようになる。
こんな感じ。
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure The last packet successfully received from the server was 30,031 milliseconds ago. The last packet sent successfully to the server was 30,030 milliseconds ago.
ここで注意しないといけないのは、単純に重いクエリを投げた場合でも、SocketTimeoutとして扱われてしまうこと。
例えばバッチ処理なんかで30秒以上かかるクエリをアプリから放り投げると例外が発生してしまう。
感想
DBはDBで死活監視、アプリはアプリで死活監視を入れてあるのを前提とすると、JDBCのパラメータでタイムアウト設定するよりは、アプリ側で使っているDBCP管理のAPIを経由する使うのがよいと思う。
ConnectTimeoutの設定値は大体ある気がするし、DBの死活監視がされているならアプリ側ではクエリタイムアウトの管理でよいかと思う。
JDBCのパラメータまで使い始めると、ただでさえ繁雑になりがちなタイムアウト値の管理がもっと複雑になってしまうような気がする。