1. ホーム
  2. .net

[解決済み】ASP.NETとSQL Server間の接続プールの問題を解決するにはどうすればいいですか?

2022-04-04 15:21:42

質問内容

ここ数日、当社のウェブサイトでこのエラーメッセージが頻繁に表示されます。

<ブロッククオート

タイムアウトが発生しました。タイムアウト時間 を取得する前に経過した。 プールからの接続。 これは プールされたすべての 接続が使用されており、最大プール のサイズに達しました。

しばらくはコードを何も変えていません。閉じていないオープンな接続をチェックするようにコードを修正しましたが、すべて問題ないことがわかりました。

  • どうすれば解決できますか?

  • このプールを編集する必要がありますか?

  • このプールの最大接続数を編集するにはどうすればよいですか?

  • アクセス数の多いWebサイトでの推奨値を教えてください。


更新情報

IISの何かを編集する必要があるのでしょうか?

更新してください。

アクティブな接続数は15から31の間で、SQLサーバーに設定されている最大許容接続数は3200接続以上であることがわかりました。31は多すぎるのか、それともASP.NET設定において何かを編集すべきでしょうか?

解決方法を教えてください。

ほとんどの場合、コネクションプーリングの問題は、次のことに関連しています。 接続リーク . あなたのアプリケーションは、おそらくデータベース接続を正しく一貫して閉じていないのでしょう。接続を開いたままにすると、.NETガベージコレクタが接続を閉じるまで、接続はブロックされたままになります。 Finalize() メソッドを使用します。

ということを確認したい。 本当に接続を閉じる . 例えば、次のコードは接続漏れを引き起こします。 .OpenClose は例外を投げます。

var connection = new SqlConnection(connectionString);

connection.Open();
// some code
connection.Close();                

正しくは、こうなります。

var connection = new SqlConnection(ConnectionString);

try
{
     connection.Open();
     someCall (connection);
}
finally
{
     connection.Close();                
}

または

using (SqlConnection connection = new SqlConnection(connectionString))
{
     connection.Open();
     someCall(connection);
}

関数 クラスメソッドから接続を返す はローカルにキャッシュし、その上で Close メソッドを使用します。例えばこのコードを使って接続をリークすることになります。

var command = new OleDbCommand(someUpdateQuery, getConnection());

result = command.ExecuteNonQuery();
connection().Close(); 

の最初の呼び出しから返された接続は getConnection() が閉じられていない。この行では、接続を閉じる代わりに、新しい接続を作成し、それを閉じようとします。

もしあなたが SqlDataReader または OleDbDataReader で、それらを閉じます。接続を閉じること自体は問題ないようですが、データリーダーオブジェクトを使用する際には、明示的に閉じるよう特別な努力をしましょう。


この記事 " なぜ接続プールはオーバーフローするのか? MSDN/SQL Magazine の "では、多くの詳細が説明され、いくつかのデバッグ方法が提案されています。

  • 実行する sp_who または sp_who2 . これらのシステム ストアド プロシージャは sysprocesses システム・テーブルには、すべての動作中のプロセスの状態と情報が表示されます。一般に、1つの接続につき1つのサーバプロセスID (SPID) が表示されます。接続文字列のアプリケーション名引数を使用して接続に名前を付けた場合、作業中の接続は簡単に見つけることができます。
  • SQLProfilerでSQL Serverプロファイラを使用する TSQL_Replay テンプレートを使用して、オープンな接続をトレースします。Profiler に慣れていれば、この方法は sp_who を使ってポーリングするよりも簡単です。
  • パフォーマンスモニターを使用して、プールと接続を監視します。この方法については、後ほど説明します。
  • コードでパフォーマンスカウンターを監視する。カウンターを抽出するルーチンを使用するか、新しい .NET PerformanceCounter コントロールを使用することにより、接続プールの健全性と確立された接続数を監視することができます。