- - PR -
カーソルがクローズされるタイミング
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2006-05-31 13:38
WebSphere5.0+Oracle9i でアプリを構築していますが、質問があります。
どちらの問題かわからないので、まずは Java 側の会議室に質問します。 JDBC 経由でDB接続していますが、Oracle 側で監視すると、 WebSphere からのコネクションに関してオープン中のカーソルが すぐにクローズされないのですが、これはこういうものですか? 問題がある場合、可能性としては何が考えられますか? アプリ側では Statement オブジェクトや ResultSet オブジェクトは 確実にクローズしているはずなので、最大カーソル数のエラーに あったことはありませんし、運用上の問題も起きていません。 ただ性能管理上、Oracle の統計情報としてカーソルがクローズされないと 取れない値があるので困っています。 カーソルのクローズはどのようなタイミングで行われるのでしょうか? Java側の問題ではなくデータベース(JDBCドライバ?)依存でしょうか。。。? よろしくお願いします。 | ||||
|
投稿日時: 2006-05-31 14:13
推測ですが,
コネクションプーリングがあるからすぐにはクローズされないのでは? したがってクローズするのは,WebSphereをとめた時では? | ||||
|
投稿日時: 2006-05-31 15:09
返信ありがとうございます。
おっしゃるとおり、コネクションプーリングされてはいますが、 コネクションのクローズとカーソルのクローズは別と思っています。 アプリから connection を close() しても実際にクローズするか は WebSphere が考えることですが、はて、カーソルはどうなの? という疑問です。 (あまりよくわかっていませんがカーソルを再利用するような 仕組みがあったりとかしますか?) | ||||
|
投稿日時: 2006-05-31 15:27
Oracle側ではどうやってオープンカーソルを監視していますか?
v$open_cursor? だとしたら、そういうもんです。
セッションによるカーソルキャッシュ、という仕組みがあって、実際にはクローズされたカーソルも、キャッシュされている限りはv$open_cursorで見えてしまいます。そういう意味では、ビュー名が不適切ですね・・・。 残念ながら、本当にオープン中のカーソルだけを知る方法はないんじゃないかと思います。 | ||||
|
投稿日時: 2006-05-31 15:57
WebLogic Server なんかだとパフォーマンスの最適化のために PreparedStatement オブジェクトを自動的にキャッシュしてトランザクションをまたがって再利用できる仕組みが用意されていたりしますね。
この場合カーソルは開いたままになります。 WebSphere でも同様の仕組みがあればそれが関係しているかもしれません。 WAS を介さず、素の JDBC プログラミングをした場合と具合が違うようでしたらどのような仕組みになっているかサポート窓口に問い合わせてみるのも一興です。 | ||||
|
投稿日時: 2006-05-31 15:58
こんにちは
私の方の環境もOracle9iなので、カーソルを確認してみたところ、 システムでは実行していないはずのクエリーのカーソルが残っていました。 解決方法があるのかはわかりませんでしたが、調べてみた 内容を書き込んで見ます。 以下はその時のV$OPEN_CURSORのSQL_TEXTの内容の一部です。 ----------------------------------------- SELECT MAX(TAG#) FROM LBAC$LAB select pol#, usr_name, usr_labels, package, privs from lbac$ ・ ・ ・ ----------------------------------------- DB接続のサンプルを作成し、以下の点を確認してみました。 1.コネクションをクローズした際のカーソル状態 ※プーリングしない カーソルは閉じていた 2.コネクションをクローズせず、ステートメントをクローズした際のカーソル状態 ※下記サンプルの無限ループ部分で擬似プーリング状態を作成して確認 カーソルが残っていた ※自分で投げたSQLのカーソルは閉じていることを確認 3.コネクション、ステートメント共にクローズしなかった場合のカーソル状態 自分で投げたSQLを含めてカーソルが残っていた 4.DB接続のみで、SQLを投げなかった場合のカーソル状態 カーソルが残っていた この結果から、JDBCでコネクションを確立しただけで、 内部的にクエリーが投げられている様に見えます。 また、コネクションプールを行っているWebシステムでも カーソル状態を確認してみましたが、ウェブサーバを止めると カーソルが消えたので、コネクションプーリングとの 複合でカーソルが残ってしまっているようです。 追記: WebServerはWebSphereではないです。 現象が違っていてインギさんの言うとおり キャッシュかもしれないですね。 ---------------------------------------------- public static void main (String[] args) { DbTest test = new DbTest(); try { test.Connection(); test.execute(); // 無限ループさせ、その間に // カーソル状態を確認。CTRL-Cでストップ while(true) { } } catch (Exception e) { e.printStackTrace(); } finally { test.close(); } } public void Connection() throws SQLException { DB接続処理 } public void execute() throws SQLException{ String sql = "select tname from tab"; try { rset = stmt.executeQuery(sql); while (rset.next()) { System.out.println(rset.getString(1)); } rset.close(); stmt.close(); // con.close(); } catch (Exception e) { e.printStackTrace(); } } public void close() { try { con.close(); } catch (Exception e) { e.printStackTrace(); } } ---------------------------------------------- [ メッセージ編集済み 編集者: zilloll 編集日時 2006-05-31 15:59 ] [ メッセージ編集済み 編集者: zilloll 編集日時 2006-05-31 16:14 ] | ||||
|
投稿日時: 2006-06-02 17:15
簡単な JSP を作って試してみました。
・jspInit で独自にDBに接続してインスタンス変数に保持し、擬似的なプーリングを再現 ・リクエストによって、WebSphere のプールからコネクションを使用するか、独自に接続したコネクションを使用するかを分岐 ・独自接続は、jspDestroy でクローズ ・リクエストで指定したテーブルからレコードを検索 ・両方のセッションをOracle側で監視。 結果 ・WebSphere のプールから取得したコネクションについては、preparedStatement を使用した場合、発行するたびにオープンカーソルが残ったままになる ・独自に接続した場合は、ResultSet を生成〜クローズの間だけ、オープンカーソルが検出される。 というわけで、インギさんのおっしゃるとおり、WebSphere 側で preparedStatement のキャッシュ機構が働いているためにカーソルが(すぐには)クローズされない、ということのようです。確かに WebSphere のリソース設定にそんな項目がありました。 ただ、WebSphere でのキャッシュ数は5個に設定されていましたが、それ以上のカーソルが検出されるのは、カーニーさんがおっしゃることが原因のようですね。 ありがとうございました。 |
1