概要
DBCP を使って Oracle に接続しているアプリで、DB ダウン時のテストを行ったところ・・・ OS の TCP 接続タイムアウト時間まで待ってタイムアウトしてしまいました。DBCP の各種タイムアウトをちゃんと設定しているのに・・・
Oracle JDBC でタイムアウト設定が必要だった、という話です。
ハマってしまった事象
DBCP で以下のタイムアウト設定をしていました。
- maxWaitMillis
- validationQueryTimeout
- defaultQueryTimeout
それぞれ 5-10s に設定し、DB を落としてテストしました。せいぜい 10s でタイムアウトエラーが発生することを期待していたのですが・・・ OS の TCP 接続タイムアウト時間でタイムアウトしました。
原因
上記の設定は、コネクションが張られている状態で有効になるようです。
コネクションが張られる前は、socket で connection timeout となるまで待ってしまいます。
対応
connection timeout を設定する必要があります。
これは DB により設定方法が異なるようです。
Oracle の場合は DBCP の connectionProperties に以下のように設定します。
<property name="connectionProperties" value="oracle.net.CONNECT_TIMEOUT=5000;oracle.jdbc.ReadTimeout=10000"/>
※接続タイムアウトを 5s に、読み取りタイムアウトを 10s に設定しています。