ほとんどの場合、接続プールの問題は接続リークに関連しています。 。アプリケーションは、データベース接続を正しく一貫して閉じていない可能性があります。接続を開いたままにすると、.NETガベージコレクターがFinalize()
を呼び出して接続を閉じるまで、接続はブロックされたままになります。 メソッド。
本当に接続を閉じていることを確認する必要があります 。たとえば、次のコードは、.Open
の間のコードの場合、接続リークを引き起こします およびClose
例外をスローします:
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つのサーバープロセスID(SPID)が表示されます。接続文字列でApplicationName引数を使用して接続に名前を付けた場合、機能している接続を簡単に見つけることができます。 - SQLProfiler
TSQL_Replay
でSQLServerProfilerを使用する 開いている接続をトレースするためのテンプレート。 Profilerに精通している場合、この方法はsp_whoを使用してポーリングするよりも簡単です。 - パフォーマンスモニターを使用して、プールと接続を監視します。この方法についてはすぐに説明します。
- コードでパフォーマンスカウンターを監視します。ルーチンを使用してカウンターを抽出するか、新しい.NET PerformanceCounterコントロールを使用して、接続プールの状態と確立された接続の数を監視できます。