- - PR -
コネクションは必ずクローズ?
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-12-01 11:56
完璧な例外処理を書こうとするとなかなか難しいところですね。
手前味噌で申し訳ないですが、以前議論したものがあるので参考にしていただけると幸いです。 http://blogs.wankuma.com/nagise/archive/2007/08/06/89056.aspx | ||||||||
|
投稿日時: 2007-12-02 03:27
繰り返しになりますが、finallyブロックでクローズをしましょう。
close() メソッドで例外が発生するような状況だとネットワーク障害など、もうプログラム内でリカバーできる状況ではありません。 そういう状況に対する対応はプログラムではなく運用手順に反映させるべきでしょう。 | ||||||||
|
投稿日時: 2007-12-03 12:55
ClassNotFoundException 発生時点でconnは生成されないので無意味な処理になっています。 whileで回して単一のコネクションに対しcloseというのも冗長な記述です。 ほかの方が言うとおりfinallyで行うほうがすっきりしますね、 | ||||||||
|
投稿日時: 2007-12-04 01:38
クローズが失敗してもwhileで回している間にネットワークが復活してクローズが成功!てなことになるのかはわかりませんが、そんなイメージで書いてみました。
インギさんがおっしゃっているように、close()での例外発生は運用で対応するようにしたほうが良いと思いました。あとfinallyブロックでクローズするようにします。 結局、close()メソッドがExceptionをスローするメソッドである限り、必ずクローズすることはできない(ORACLEサーバー上のリソースは開放されない)ということになるでしょうか? | ||||||||
|
投稿日時: 2007-12-04 01:56
前にも書きましたが、Connection#close()がスローするのは、
Exceptionではなく、SQLExceptionです。意味が全く違います。 で、
close()が例外をスローする可能性があるのと、 必ずクローズできないのとは関連性はありません。 仮に例外をスローしない設計になっていても、 close()の直前にネットワーク障害が発生したら失敗しますよね。 さらに、SQLExceptionをスローしなくても、 RuntimeExceptionやErrorのサブクラスがスローされる場合も考えられますよね。 逆に実装では例外をスローしないが、 実装しているインターフェイスのメソッドに、 throws節が記述されているものもあります。 (他のAPIなど) したがって、close()の確実性と例外の有無は全く関係ないのです。 | ||||||||
|
投稿日時: 2007-12-08 18:48
DriverManager.getConnection( jdbc:oracle:thin:@localhost:1521:ORCL", "scott", "tiger" );
上記の処理単体でみたときSQLExceptionが発生した場合、コネクションのクローズ処理は必要でしょうか? (SQLExceptionが発生したということはコネクションは取得できていないということでしょうか?) 同様に stmt = con.createStatement(); でSQLExceptionが発生したときのステートメントのクローズ、 rs = stmt.executeQuery( SQL文 ); でSQLExceptionが発生したときのリザルトセットのクローズ、 こちらもそれぞれクローズ処理は必要でしょうか? [ メッセージ編集済み 編集者: Orphan 編集日時 2007-12-08 19:15 ] | ||||||||
|
投稿日時: 2007-12-08 20:44
そもそもConnectionのインスタンスは取得できないので、 クローズそのものができないでしょう。
例外の種類やケースバイケースです。 接続が有効な場合も十分に考えられます。 JDK6から、「一時的な問題であり、継続処理や再処理が可能なことを示す例外」 が増えました。SQLExceptionのサブクラスです。 この例外の場合は再実行という手段もありなので、 クローズはしない場合も考えられます。 処理が終わったら、基本的にどんな場合でも、 finally節で、クローズを試みるのがいいと思います。 私の場合は例外を握りつぶすタイプの、 クローズ専用ユーティリティメソッドをよく使います。 で、必ずfinally節で呼び出すようにしています。 | ||||||||
|
投稿日時: 2007-12-08 23:36
スマートにfinallyでまとめてはいかがですか?
仮にNullPointerExceptionが発生したら、con.close()はとおらないですよね? while(true) break も意味不明です。 必要ありません。 以下のような感じで、、、、
どちらがスマートに見えて、メンテしやすそうですか? ちなみにDBの接続切断等でスローされるSQLExcetionは アプリでの対応方法はほぼありません。 ResultSet, Statement, PreparedStatement のクローズは コネクションのクローズより重要です。 OracleではConnectionオブジェクトは V$SESSIONに対応します。 ResultSet は V$OPEN_CURSORS に対応します。 ResultSetをクローズしない場合は、 MAX_CURSORエラーになります。 ご参考に。 [ メッセージ編集済み 編集者: raystar 編集日時 2007-12-08 23:40 ] |