ほとんどの場合、接続プールの問題は「接続リーク」に関連しています。あなたのアプリケーションはおそらくそのデータベース接続を正しくそして一貫して閉じません。接続を開いたままにすると、.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)が表示されます。接続文字列でアプリケーション名引数を使用して接続に名前を付けた場合、機能している接続を簡単に見つけることができます。
TSQL_Replay
開いている接続を追跡するには、SQL ServerプロファイラとSQLProfiler テンプレートを使用します。プロファイラーに慣れている場合、この方法はsp_whoを使用してポーリングするよりも簡単です。
- パフォーマンスモニターを使用して、プールと接続を監視します。この方法についてはすぐに説明します。
- コードでパフォーマンスカウンターを監視します。ルーチンを使用してカウンターを抽出するか、新しい.NET PerformanceCounterコントロールを使用して、接続プールの状態と確立された接続の数を監視できます。