.NET Framework Data Provider for SQL Server の接続プール
接続をプールすると、アプリケーションのパフォーマンスとスケーラビリティを大幅に改善できます。.NET Framework Data Provider for SQL Server は ADO.NET クライアント アプリケーションに自動的に接続プールを提供します。また、接続プール機能の動作を制御する接続文字列修飾子を指定することもできます (このトピックの後の「接続文字キーワードによる接続プールの制御」のセクションを参照してください)。
プールの作成と割り当て
接続が開かれると、厳密一致のアルゴリズムに基づいて接続プールが作成され、接続内の接続文字列に関連付けられます。各接続プールが別の接続文字列に関連付けられます。新しい接続が開かれたとき、接続文字列が既存のプールと厳密に一致しない場合は、新しいプールが作成されます。
3 つの新しい SqlConnection オブジェクトを作成し、2 つの接続プールだけでこの 3 つのオブジェクトを管理する例を次に示します。1 番目の接続文字列と 2 番目の接続文字列では、Initial Catalog
に割り当てる値が異なります。
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind";
conn.Open();
// Pool A is created.
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=pubs";
conn.Open();
// Pool B is created because the connection strings differ.
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind";
conn.Open();
// The connection string matches pool A.
接続プールは一度作成されるとアクティブなプロセスが終了するまで破棄されません。アクティブでないプールまたは空のプールを維持するためには、最小限のシステム オーバーヘッドが発生します。
接続の追加
一意の接続文字列ごとに 1 つの接続プールが作成されます。プールが作成された段階で、複数の接続オブジェクトが作成されてそのプールへ追加され、最小プール サイズ要件を満たします。必要に応じて、最大プール サイズに達するまで、接続がプールへ追加されます。
SqlConnection オブジェクトが要求されたとき、プールに使用可能な接続がある場合はプールから SqlConnection オブジェクトを取得します。使用可能な接続とは、サーバーへの有効なリンクを持つ接続のうち、現在使用中でないか、一致するトランザクション コンテキストを持っているか、またはどのトランザクション コンテキストにも関連付けられていない接続のことです。
最大プール サイズに達すると、使用可能な接続を取得できなくなり、要求はキューに置かれます。接続プーラーは、接続がプールに解放されたときに接続の再割り当てを行ってそれらの要求に応えます。Connection オブジェクトに対して Close メソッドまたは Dispose メソッドを呼び出すと、接続は解放され、プールに戻されます。
**注意 **接続がプールに返されるようにするために、接続を使い終えたら必ず Connection を終了することをお勧めします。これを行うには、Connection オブジェクトの Close メソッドまたは Dispose メソッドを使用します。明示的に終了されていない接続は、プールに追加したり返したりすることができないことがあります。たとえば、スコープ外に出ても、明示的に終了されていない接続は、最大プール サイズに達した時点でその接続がまだ有効である場合にだけ接続プールに返されます。
メモ クラスの Finalize メソッド内で Connection、DataReader、またはその他のマネージ オブジェクトの Close または Dispose を呼び出さないでください。終了処理では、クラスに直接所有されているアンマネージ リソースだけを解放してください。クラスがアンマネージ リソースを所有していない場合は、クラス定義に Finalize メソッドを含めないでください。詳細については、「ガベージ コレクションのプログラミング」を参照してください。
接続の削除
接続の有効期間が経過したとき、またはサーバーとの接続が切断されているのを検出したとき、接続プーラーはプールから接続を削除します。この作業を実行できるのは、サーバーとの通信を試みた後だけです。接続がサーバーに接続していないことがわかると、その接続は無効としてマークされます。接続プーラーは、定期的に接続プールをスキャンし、プールから解放して無効としてマークするオブジェクトを検索します。その後、それらの接続は永久に削除されます。
既に存在しないサーバーへの接続が存在する場合は、接続プーラーが、その接続が切断されていることをまだ検出せず、無効というマークを付けていない状況であっても、プールからその接続を削除できます。このような状況が発生したときは、例外が生成されます。ただし、その場合も開発者は接続を終了して解放し、プールへ返す必要があります。
トランザクションのサポート
接続はプールから取り出され、トランザクション コンテキストに基づいて割り当てられます。要求スレッドのコンテキストと割り当てられた接続は一致している必要があります。したがって、各接続プールは、実際にはトランザクション コンテキストに関連付けられていない接続の部分と、それぞれが特定のトランザクション コンテキストに関連付けられている接続を含む N 個の部分に分かれています。
接続が終了すると、その接続は解放されてプールへ返り、さらに、そのトランザクション コンテキストに基づいて特定のサブプールへ返ります。そのため、分散トランザクションが保留状態である場合を含め、エラーを発生させることなく、開発者が接続を終了させることは可能です。これにより、分散トランザクションを後でコミットまたはアボートできます。
接続文字列キーワードによる接続プールの制御
SqlConnection オブジェクトの ConnectionString プロパティは、接続プール ロジックの動作を調整するために使用できる接続文字列キーおよび値のペアをサポートします。
接続プールの動作を調整するための ConnectionString 値についての説明を次の表に示します。
名前 | 既定値 | 説明 |
---|---|---|
Connection Lifetime | 0 | 接続がプールに返された時点で、その接続の作成時刻と現在の時刻を比較し、その時間の長さ (秒) が Connection Lifetime で指定した値を超えている場合は、その接続が破棄されます。これは、クラスタ構成を採用している状況で、実行中のサーバーと、オンラインになったばかりのサーバーの間での、負荷を強制的に分散するのに便利です。
値ゼロ (0) を指定した場合は、プールされている接続に、最大のタイムアウトが割り当てられます。 |
Connection Reset | 'true' | プールから接続を削除するときにデータベース接続をリセットするかどうかを指定します。Microsoft SQL Server Version 7.0 の場合、false に設定すると、接続の取得時に追加のサーバーのラウンド トリップ (クライアントとサーバーとの間でのなんらかのデータのやり取り) を行いません。ただし、データベース コンテキストなどの接続状態はリセットされないので注意してください。 |
Enlist | 'true' | true に設定すると、トランザクション コンテキストが存在する場合、プーラーは自動的に、作成スレッドの現在のトランザクション コンテキストの中に、その接続を参加させます。 |
Max Pool Size | 100 | プールに格納できる最大接続数。 |
Min Pool Size | 0 | プールで維持できる最小接続数。 |
Pooling | 'true' | true に設定すると、接続が適切なプールから取り出されるか必要に応じて作成され、適切なプールに追加されます。 |
接続プールのためのパフォーマンス カウンタ
.NET Framework Data Provider for SQL Server は、いくつかのパフォーマンス カウンタを追加します。これらのカウンタを使用すると、接続プール機能の特性の微調整、失敗した接続に関連して断続的に発生する問題の検出、SQL Server へのタイムアウト要求に関連する問題の検出などが可能になります。
次の表で、.NET CLR Data パフォーマンス オブジェクト下にあるパフォーマンス モニタからアクセスできる接続プール カウンタを示しています。
カウンタ | 説明 |
---|---|
SqlClient: プールされている接続とプールされていない接続の現在の数。 | プールされている接続とプールされていない接続を含めた現在の接続数。 |
SqlClient: 現在プールされている接続数。 | このプロセスに関連付けられているすべてのプール内の現在の接続数。 |
SqlClient: 現在の接続プール数。 | このプロセスに関連付けられている現在のプール数。 |
SqlClient: プールされている接続のピーク時の数。 | プロセス開始後のプール内の最高 (ピーク時) 接続数。メモ : このカウントは、特定のプロセス インスタンスに関連付けられているときだけ使用できます。_Global インスタンスは常に 0 を返します。 |
SqlClient: 失敗した接続の合計数。 | なんらかの理由で接続を確立することに失敗した接続の合計数。 |
メモ .NET Framework Data Provider for SQL Server のパフォーマンス カウンタを ASP.NET アプリケーションと共に使用する場合は、_Global インスタンスだけが使用できます。その結果、パフォーマンス カウンタが返す値は、すべての ASP.NET アプリケーションのカウンタ値の合計となります。
参照
ADO.NET でのデータ ソースへの接続 | .NET データ プロバイダによるデータのアクセス | SqlConnection クラス