Windows上からJDBCドライバを介してRedHat上のOracleにアクセスする際に、java.sql.Statement#setQueryTimeout(int)
が効かない事象にぶち当たりました・・・ 指定した時間を超えてもクエリーが返ってこない
解決方法
いきなりですが、解決方法を紹介しましょう。この事象は、JVMのシステムプロパティとして以下のプロパティを追加することで解決することができます。
-Doracle.net.disableOob=true
検証はしていませんが、「OracleのJDBCドライバのJavaDoc」に定数定義があるので、JDBCのコネクションを作成する際に指定するプロパティでも指定できるのかもしれません。
この解決方法は、(調べた範囲では)Oracleの公式ドキュメント上には明記されておらず、ぐるぐるググっていたら、「Oracle SQL Developerの掲示板のスレッド」がヒットし、この解決方法にたどり着きました。
さらにOut Of Band(OOB)でOracleのサイトを検索していたら、「Oracle Database Net Services Administrator's Guide」の中に「Disable Out-of-Band Break」というパラメータの説明がありました。説明を読むと・・「中断メッセージ(キャンセル指示)を「緊急データ」として送るか否かを制御するパラメータ」みたいです。
Out of Band(OOB) Breaksって?
正直なところ私もちゃんと理解できていないのですが・・・ コマンドであれば「Ctrl + C」などを使ったクエリのキャンセル、JDBCであれば
setQueryTimeout
で指定した時間を経過したあとのcancel
処理の際などに、Out of Band Breaks「緊急データ(URGパケット)」としてOracleに通知される仕組みになっているみたいです。これは、先ほど紹介したJavaDocの定数説明にも記載があり、11gから採用されたようです。
クエリーがキャンセルされなかった理由は?
何かしらの理由でお使いのプラットフォームがOut of Bandをサポートしていない場合は、Out of Band Breaks方式でクエリーをキャンセルすることができないようです。そのようなプラットフォームでは、In Band方式を利用することでキャンセルすることができます。(Windowsはデフォ?だとOut of Bandがサポートされてないようです・・・)
まとめ
単なるJava開発者にとっては、ネットワークは奥が深すぎる・・・ とりあえず、解決方法がみつかってよかった・・・。