QA@IT
この質問・回答は、@ITの旧掲示板からインポートされたものです。

DBへの接続プールが満杯となる

いつもお世話になっております。

VB.NET 2003、SQL Server2000 SP3aの環境で、Webアプリケーションを
構築しております。

内容は小規模なもので、まだ個人レベルによるテスト段階なのですが、
時々以下のようなエラーが発生します。
「タイムアウトに達しました。プールから接続を取得する前に
タイムアウト期間が過ぎました。プールされた接続がすべて使用中で、
プール サイズの制限値に達した可能性があります。」

何が問題となっているか色々調べている最中なのですが、
パフォーマンスカウンタにて、
パフォーマンスオブジェクト:SQL Server:General Statics
カウンタ:User Connections
を見てみると、アプリケーションの使用中にこれがどんどん
増加し、大体100を超えた段階でこのエラーが発生している
ことが分かりました。

接続プールについては、特に意識せずデフォルトのまま
使用しているのですが、使用中に
このように増え続けるというのはやはりアプリケーション
の作りがまずいのでしょうか?

DBへの接続は一種類しか無く、
Dim CnString As String = "Data Source=(local);Initial Catalog=DB_NAME;Integrated Security=SSPI;"
といった形で最初に定義して、

Dim cn As New SqlConnection(CnString)
Dim cmd As New SqlCommand("SQL文", cn)

cn.Open()
Dim dr As SqlDataReader = cmd.ExecuteReader
・・・・・
dr.Close()
cn.Close()

という形で使っています。

cn.Open()のあと、cn.Close()が無いパターンがあるのではと考え
何度かチェックしたのですが、漏れはなさそうです。

こういった問題が発生した場合、どのようにアプローチして
解決していけばよいのでしょうか?

どなたかアドバイスいただけると幸いです。

情報不足でしたらその旨ご指摘下さい。
よろしくお願いいたします。

質問者:やんもり

回答

cmdのconnectionとtransactionも破棄してみてください。
(例)
With cmd
.connection=nothing
.transaction=nothing
End with

それでもだめでしょうか?

投稿者:TEA-BREAK

編集 履歴 (0)

TEA-BREAKさんアドバイスありがとうございます。
結果報告が遅くなり、申し訳ありません。

まだ、細かなテストは出来ていないのですが、
cn.Close() のあとに、教えていただいた
cmd.Connection = Nothing
cmd.Transaction = Nothing
を追加していくことで、user connection の増えかたが
多少改善されたように感じます。

ただ、それでもエラーとなるときはあるので、もう少し
検証していきたいのですが、
user connection がどういったタイミングで作られ、
どういったタイミングで消えるのかという仕組みや
接続プールとの関係がよく分かっていないため、
どうやって検証するのがよいか、よい方法を思いつけずにいます。

この辺を若干解説していただけると非常に助かるのですが…
もしくは、MSDNかどこかに参考になる説明があるでしょうか?
(インターネットで色々検索して見ましたが、これというものを
見つけられずにいます…)

投稿者:やんもり

編集 履歴 (0)

こんばんは。TEA-BREAKです。
申し訳ないのですが、原因・理由を把握しておりません・・・。

実は、私も同じような現象が発生し、悩んだ事があったのです。
(私の場合はVB.NET+Oracle9iだったのですが。)

コネクションもデータリーダもクローズしているのにどんどん
プールしている数が増えていって、同様に100を超えた時点で、
上限を超えた旨のメッセージが吐かれて、終了してました。

色々調べたのですが、原因を突き止めるまでには至らなかった次第です。

私が行った検証は
ステップ実行しながら、Oracleのプーリング数をそのつど確認致しました。

結果は
コマンドオブジェクトの破棄を行わない場合、プーリング数が増える一方だった
のに対し、破棄を行った場合、増えた分はきっちり減少し改善されました。
(エラーはもちろん発生しなくなりました。)

正しい理由がわからないので、この対応が正しいのか疑問が残りますが、
求めている結果を出せたので、その場は良しと致しました。
中途半端で申し訳ございません。

投稿者:TEA-BREAK

編集 履歴 (0)

私もASP.NET(VB)+Oracle9i+OO4Oで開発をしていて、接続プールを
使用しています。

で、Oracleから現在のプール数ってどうやって把握するのですか?

投稿者:ttcoupe

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。