SQL Server の接続プール (ADO.NET)SQL Server Connection Pooling (ADO.NET)

通常、データベース サーバーへの接続は、時間のかかるいくつかの手順で構成されています。Connecting to a database server typically consists of several time-consuming steps. ソケットまたは名前付きパイプなどの物理チャネルの確立、サーバーとの最初のハンドシェイクの実行、接続文字列の情報の解析、サーバーによる接続の認証、現在のトランザクションへ参加するための検証などの手順を行う必要があります。A physical channel such as a socket or a named pipe must be established, the initial handshake with the server must occur, the connection string information must be parsed, the connection must be authenticated by the server, checks must be run for enlisting in the current transaction, and so on.

実際には、ほとんどのアプリケーションで、1 つまたはいくつかの違いがあるだけの構成を接続に使用しています。In practice, most applications use only one or a few different configurations for connections. つまり、アプリケーションの実行時に、多数の同一の接続が繰り返し開かれ、閉じられているのです。This means that during application execution, many identical connections will be repeatedly opened and closed. 接続を開くコストを最小限に抑えるADO.NETADO.NETと呼ばれる最適化の手法を使用して接続プーリングです。To minimize the cost of opening connections, ADO.NETADO.NET uses an optimization technique called connection pooling.

接続プールは、新しく開く必要のある接続の数を減らします。Connection pooling reduces the number of times that new connections must be opened. プーラーの物理的な接続の所有権を保持します。The pooler maintains ownership of the physical connection. プーラーは、任意の接続構成それぞれのアクティブな接続のセットをそのまま保持して、接続を管理します。It manages connections by keeping alive a set of active connections for each given connection configuration. この接続の Open を呼び出すと、プーラーは、プールに使用可能な接続があるかどうかを確認します。Whenever a user calls Open on a connection, the pooler looks for an available connection in the pool. プールされた接続が使用できる場合は、新しい接続を開く代わりに、プールされた接続を呼び出し元に返します。If a pooled connection is available, it returns it to the caller instead of opening a new connection. アプリケーションが接続で Close を呼び出すと、プーラーは接続を閉じる代わりに、プールされたアクティブな接続のセットに接続を返します。When the application calls Close on the connection, the pooler returns it to the pooled set of active connections instead of closing it. 接続がプールに返されると、その接続は、次の Open 呼び出しで再度使用できる状態になります。Once the connection is returned to the pool, it is ready to be reused on the next Open call.

同じ構成を持つ接続のみをプールすることができます。Only connections with the same configuration can be pooled. ADO.NETADO.NET は同時に複数のプールを保持し、各プールでの構成は 1 つです。 keeps several pools at the same time, one for each configuration. 接続は接続文字列によってプール内で区別されます。また、統合セキュリティを使用している場合は、Windows ID によっても区別されます。Connections are separated into pools by connection string, and by Windows identity when integrated security is used. 接続がプールされるかどうかは、その接続がトランザクションに参加しているかどうかにも依存します。Connections are also pooled based on whether they are enlisted in a transaction. ChangePassword を使用すると、SqlCredential インスタンスは接続プールに影響します。When using ChangePassword, the SqlCredential instance affects the connection pool. ユーザー ID とパスワードが同じでも、SqlCredential のインスタンスごとに異なる接続プールが使用されます。Different instances of SqlCredential will use different connection pools, even if the user ID and password are the same.

接続をプールすると、アプリケーションのパフォーマンスとスケーラビリティを大幅に改善できます。Pooling connections can significantly enhance the performance and scalability of your application. ADO.NETADO.NET では、接続プールが既定で有効になっています。By default, connection pooling is enabled in ADO.NETADO.NET. 明示的に無効にしない限り、プーラーは、アプリケーションで接続が開かれたり、閉じられたりする際に接続を最適化します。Unless you explicitly disable it, the pooler optimizes the connections as they are opened and closed in your application. また、接続プール機能の動作を制御する接続文字列修飾子を指定することもできます。You can also supply several connection string modifiers to control connection pooling behavior. 詳細については、このトピックで後述する「接続文字列キーワードによる接続プールの制御」を参照してください。For more information, see "Controlling Connection Pooling with Connection String Keywords" later in this topic.

注意

接続プールが有効になっている場合とタイムアウト エラーや他のログイン エラーが発生した場合は、例外がスローされ、それ以降に接続を試みると、5 秒間の "ブロック期間" 中失敗します。When connection pooling is enabled, and if a timeout error or other login error occurs, an exception will be thrown and subsequent connection attempts will fail for the next five seconds, the "blocking period". ブロック期間内にアプリケーションが接続を試みると、最初の例外が再度スローされます。If the application attempts to connect within the blocking period, the first exception will be thrown again. ブロック期間の終了後も失敗が続く場合は、最大 1 分として、新しいブロック期間は前のブロック期間の 2 倍の長さになります。Subsequent failures after a blocking period ends will result in a new blocking periods that is twice as long as the previous blocking period, up to a maximum of one minute.

プールの作成と割り当てPool Creation and Assignment

接続が最初に開かれると、完全一致のアルゴリズムに基づいて接続プールが作成され、接続内の接続文字列に関連付けられます。When a connection is first opened, a connection pool is created based on an exact matching algorithm that associates the pool with the connection string in the connection. 各接続プールが別の接続文字列に関連付けられます。Each connection pool is associated with a distinct connection string. 新しい接続が開かれたとき、接続文字列が既存のプールと完全に一致しない場合は、新しいプールが作成されます。When a new connection is opened, if the connection string is not an exact match to an existing pool, a new pool is created. 接続は、プロセス、アプリケーション ドメイン、接続文字列、Windows ID (統合セキュリティを使用している場合) ごとにプールされます。Connections are pooled per process, per application domain, per connection string and when integrated security is used, per Windows identity. また、接続文字列は完全に一致していることが必要です。同じ接続に対してキーワードを異なる順序で指定すると別々にプールされます。Connection strings must also be an exact match; keywords supplied in a different order for the same connection will be pooled separately.

3 つの新しい SqlConnection オブジェクトを作成し、2 つの接続プールだけでこの 3 つのオブジェクトを管理する C# の例を次に示します。In the following C# example, three new SqlConnection objects are created, but only two connection pools are required to manage them. 1 番目の接続文字列と 2 番目の接続文字列では、Initial Catalog に割り当てる値が異なります。Note that the first and second connection strings differ by the value assigned for Initial Catalog.

using (SqlConnection connection = new SqlConnection(  
  "Integrated Security=SSPI;Initial Catalog=Northwind"))  
    {  
        connection.Open();        
        // Pool A is created.  
    }  

using (SqlConnection connection = new SqlConnection(  
  "Integrated Security=SSPI;Initial Catalog=pubs"))  
    {  
        connection.Open();        
        // Pool B is created because the connection strings differ.  
    }  

using (SqlConnection connection = new SqlConnection(  
  "Integrated Security=SSPI;Initial Catalog=Northwind"))  
    {  
        connection.Open();        
        // The connection string matches pool A.  
    }  

接続文字列で MinPoolSize が指定されていない、またはゼロに指定されている場合、プール内の接続は、アクティブではない一定の期間後に閉じられます。If MinPoolSize is either not specified in the connection string or is specified as zero, the connections in the pool will be closed after a period of inactivity. ただし、MinPoolSize がゼロより大きい値に設定されている場合、接続プールは、AppDomain がアンロードされ、プロセスが終了するまで破棄されません。However, if the specified MinPoolSize is greater than zero, the connection pool is not destroyed until the AppDomain is unloaded and the process ends. アクティブでないプールまたは空のプールを維持するためには、最小限のシステム オーバーヘッドが発生します。Maintenance of inactive or empty pools involves minimal system overhead.

注意

フェールオーバーなど、致命的なエラーが発生すると、プールは自動的にクリアされます。The pool is automatically cleared when a fatal error occurs, such as a failover.

接続の追加Adding Connections

一意の接続文字列ごとに 1 つの接続プールが作成されます。A connection pool is created for each unique connection string. プールが作成された段階で、複数の接続オブジェクトが作成されてそのプールへ追加され、最小プール サイズ要件を満たします。When a pool is created, multiple connection objects are created and added to the pool so that the minimum pool size requirement is satisfied. 必要に応じて、指定された最大プール サイズ (既定は 100) に達するまで、接続がプールへ追加されます。Connections are added to the pool as needed, up to the maximum pool size specified (100 is the default). 接続が終了または破棄されると、その接続は解放され、プールに戻されます。Connections are released back into the pool when they are closed or disposed.

SqlConnection オブジェクトが要求されると、プールに使用可能な接続がある場合はプールから取得されます。When a SqlConnection object is requested, it is obtained from the pool if a usable connection is available. 使用可能な接続とは、サーバーへの有効なリンクを持つ接続のうち、使用中でないか、一致するトランザクション コンテキストを持っているか、またはどのトランザクション コンテキストにも関連付けられていない接続のことです。To be usable, a connection must be unused, have a matching transaction context or be unassociated with any transaction context, and have a valid link to the server.

接続プーラーは、接続がプールに解放されたときに接続の再割り当てを行って、接続に対する要求に応えます。The connection pooler satisfies requests for connections by reallocating connections as they are released back into the pool. 最大プール サイズに達すると、使用可能な接続を取得できなくなり、要求はキューに置かれます。If the maximum pool size has been reached and no usable connection is available, the request is queued. プーラーは、タイムアウト (既定は 15 秒) に達するまで接続の再利用を試みます。The pooler then tries to reclaim any connections until the time-out is reached (the default is 15 seconds). 接続がタイムアウトになる前に、プーラーが要求を満たすことができない場合は、例外がスローされます。If the pooler cannot satisfy the request before the connection times out, an exception is thrown.

注意事項

接続がプールに返されるようにするために、接続を使い終えたら必ず接続を終了することを強くお勧めします。We strongly recommend that you always close the connection when you are finished using it so that the connection will be returned to the pool. この操作は、Close オブジェクトの Dispose または Connection メソッドを使用するか、あるいは C# の using ステートメントまたは UsingVisual BasicVisual Basic ステートメント内ですべての接続を開くことによって実行できます。You can do this using either the Close or Dispose methods of the Connection object, or by opening all connections inside a using statement in C#, or a Using statement in Visual BasicVisual Basic. 明示的に終了されていない接続は、プールに追加したり返したりすることができないことがあります。Connections that are not explicitly closed might not be added or returned to the pool. 詳細については、次を参照してください。ステートメントを使用してまたはする方法: システム リソースを破棄Visual BasicVisual Basicします。For more information, see using Statement or How to: Dispose of a System Resource for Visual BasicVisual Basic.

注意

クラスの Close メソッド内で DisposeConnection、またはその他のマネージ オブジェクトの DataReader または Finalize を呼び出さないでください。Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. 終了処理では、クラスに直接所有されているアンマネージ リソースだけを解放してください。In a finalizer, only release unmanaged resources that your class owns directly. クラスがアンマネージ リソースを所有していない場合は、クラス定義に Finalize メソッドを含めないでください。If your class does not own any unmanaged resources, do not include a Finalize method in your class definition. 詳細については、次を参照してください。ガベージ コレクションです。For more information, see Garbage Collection.

注意

接続が接続プールからフェッチされたり接続プールに返される場合、ログイン イベントとログアウト イベントはサーバーで発生しません。Login and logout events will not be raised on the server when a connection is fetched from or returned to the connection pool. これは、接続プールに返されるときに接続が実際には終了していないためです。This is because the connection is not actually closed when it is returned to the connection pool. 詳細については、次を参照してください。 Audit Login Event ClassAudit Logout イベント クラスSQL ServerSQL Serverオンライン ブック。For more information, see Audit Login Event Class and Audit Logout Event Class in SQL ServerSQL Server Books Online.

接続の削除Removing Connections

接続プール機能は、アイドル状態の時間が約 4-8 分になったか、サーバーとの接続が切断されたことをプール機能が検出した場合に、プールからの接続を削除します。The connection pooler removes a connection from the pool after it has been idle for approximately 4-8 minutes, or if the pooler detects that the connection with the server has been severed. サーバーとの通信を試みた後にのみ、切断されたサーバー接続が検出可能になることに注意してください。Note that a severed connection can be detected only after attempting to communicate with the server. 接続がサーバーに接続していないことがわかると、その接続は無効としてマークされます。If a connection is found that is no longer connected to the server, it is marked as invalid. 無効な接続は、閉じられるか、または再利用された場合のみ、接続プールから削除されます。Invalid connections are removed from the connection pool only when they are closed or reclaimed.

既に存在しないサーバーへの接続が存在する場合は、接続プーラーが、その接続が切断されていることをまだ検出せず、無効というマークを付けていない状況のときでも、プールからその接続を削除できます。If a connection exists to a server that has disappeared, this connection can be drawn from the pool even if the connection pooler has not detected the severed connection and marked it as invalid. この機能は、接続がまだ有効であることを確認するオーバーヘッドによってサーバーへのラウンド トリップが実行されることにより、プーラーの利点が失われてしまうことを防ぐためにあります。This is the case because the overhead of checking that the connection is still valid would eliminate the benefits of having a pooler by causing another round trip to the server to occur. この状況が発生した場合は、接続の使用を最初に試みたときに接続が切断されていることが検出され、例外がスローされます。When this occurs, the first attempt to use the connection will detect that the connection has been severed, and an exception is thrown.

プールのクリアClearing the Pool

ADO.NETADO.NET 2.0 では、プールをクリアするために、ClearAllPoolsClearPool という 2 つの新しいメソッドが導入されました。 2.0 introduced two new methods to clear the pool: ClearAllPools and ClearPool. ClearAllPools は、指定されたプロバイダーの接続プールをクリアし、ClearPool は、特定の接続に関連付けられた接続プールをクリアします。ClearAllPools clears the connection pools for a given provider, and ClearPool clears the connection pool that is associated with a specific connection. これらのメソッドが呼び出されたときに使用中の接続がある場合は、適切にマーク付けされ、If there are connections being used at the time of the call, they are marked appropriately. 接続が閉じられるとプールに返されずに破棄されます。When they are closed, they are discarded instead of being returned to the pool.

トランザクションのサポートTransaction Support

接続はプールから取り出され、トランザクション コンテキストに基づいて割り当てられます。Connections are drawn from the pool and assigned based on transaction context. 接続文字列で Enlist=false が指定されていない限り、接続プールは、接続を Current コンテキストの中に参加させます。Unless Enlist=false is specified in the connection string, the connection pool makes sure that the connection is enlisted in the Current context. 接続が閉じられ、参加した System.Transactions トランザクションと共にプールに返されると、同じ System.Transactions トランザクションを持つ接続プールに対する次の要求でも、使用可能であれば同じ接続を返すように接続が保持されます。When a connection is closed and returned to the pool with an enlisted System.Transactions transaction, it is set aside in such a way that the next request for that connection pool with the same System.Transactions transaction will return the same connection if it is available. このような要求が発行された場合で、なおかつ、プールされた接続が使用できない場合は、プールの非トランザクション部分から接続を取り出して参加させます。If such a request is issued, and there are no pooled connections available, a connection is drawn from the non-transacted part of the pool and enlisted. プールのどちらの領域にも使用できる接続がない場合は、新しい接続を作成して参加させます。If no connections are available in either area of the pool, a new connection is created and enlisted.

接続が終了すると、その接続は解放されてプールへ返り、さらに、そのトランザクション コンテキストに基づいて特定のサブプールへ返ります。When a connection is closed, it is released back into the pool and into the appropriate subdivision based on its transaction context. そのため、分散トランザクションが保留状態である場合を含め、エラーを発生させることなく、開発者が接続を終了させることは可能です。Therefore, you can close the connection without generating an error, even though a distributed transaction is still pending. これにより、分散トランザクションを後でコミットまたは中止できます。This allows you to commit or abort the distributed transaction later.

接続文字列キーワードによる接続プールの制御Controlling Connection Pooling with Connection String Keywords

ConnectionString オブジェクトの SqlConnection プロパティは、接続プール ロジックの動作を調整するために使用できる接続文字列キーおよび値のペアをサポートします。The ConnectionString property of the SqlConnection object supports connection string key/value pairs that can be used to adjust the behavior of the connection pooling logic. 詳細については、「ConnectionString」を参照してください。For more information, see ConnectionString.

プールの断片化Pool Fragmentation

プールの断片化は、プロセスが終了するまで解放されないプールを多数作成できる Web アプリケーションの多くで一般的な問題です。Pool fragmentation is a common problem in many Web applications where the application can create a large number of pools that are not freed until the process exits. これにより、多数の接続が開いたままになってメモリを消費し、パフォーマンスが低下します。This leaves a large number of connections open and consuming memory, which results in poor performance.

統合セキュリティによるプールの断片化Pool Fragmentation Due to Integrated Security

接続は、接続文字列とユーザー ID に基づいてプールされます。Connections are pooled according to the connection string plus the user identity. したがって、Web サイトで基本認証または Windows 認証を使用していて、統合セキュリティ ログインを使用している場合は、1 ユーザーにつき 1 つのプールが作成されます。Therefore, if you use Basic authentication or Windows Authentication on the Web site and an integrated security login, you get one pool per user. これによって、単一のユーザーによる後続のデータベース要求のパフォーマンスが向上しますが、他のユーザーによって作成された接続は使用できません。Although this improves the performance of subsequent database requests for a single user, that user cannot take advantage of connections made by other users. また、1 ユーザーにつき少なくとも 1 つの接続がデータベース サーバーに存在することになります。It also results in at least one connection per user to the database server. これは、開発者がセキュリティおよび監査要件に対して、特定の Web アプリケーションのアーキテクチャに重点を置く必要があるために起こる副作用です。This is a side effect of a particular Web application architecture that developers must weigh against security and auditing requirements.

多数のデータベースによるプールの断片化Pool Fragmentation Due to Many Databases

インターネット サービス プロバイダーの多くは、1 つのサーバー上で複数の Web サイトをホストしています。Many Internet service providers host several Web sites on a single server. インターネット サービス プロバイダーは、1 つのデータベースを使用してフォーム認証ログインを確認し、そのユーザーまたはユーザー グループの特定のデータベースへの接続を開きます。They may use a single database to confirm a Forms authentication login and then open a connection to a specific database for that user or group of users. 認証データベースへの接続はプールされ、すべてのユーザーが使用できるようになります。The connection to the authentication database is pooled and used by everyone. ただし、各データベースに対して個別の接続のプールが存在するため、サーバーへの接続数が増加します。However, there is a separate pool of connections to each database, which increase the number of connections to the server.

これもまた、アプリケーションのデザインの副作用です。This is also a side-effect of the application design. SQL ServerSQL Server に接続するときにセキュリティを損なうことなく、この副作用を回避する比較的簡単な方法があります。There is a relatively simple way to avoid this side effect without compromising security when you connect to SQL ServerSQL Server. 各ユーザーまたはグループの個別のデータベースに接続する代わりに、サーバー上の同じデータベースに接続してから、Transact-SQLTransact-SQL USE ステートメントを実行して目的のデータベースに変更します。Instead of connecting to a separate database for each user or group, connect to the same database on the server and then execute the Transact-SQLTransact-SQL USE statement to change to the desired database. master データベースへの最初の接続を作成し、databaseName 文字列変数で指定した目的のデータベースに切り替えるコードを次に示します。The following code fragment demonstrates creating an initial connection to the master database and then switching to the desired database specified in the databaseName string variable.

' Assumes that command is a valid SqlCommand object and that  
' connectionString connects to master.  
    command.Text = "USE DatabaseName"  
Using connection As New SqlConnection(connectionString)  
    connection.Open()  
    command.ExecuteNonQuery()  
End Using  
// Assumes that command is a SqlCommand object and that  
// connectionString connects to master.  
command.Text = "USE DatabaseName";  
using (SqlConnection connection = new SqlConnection(  
  connectionString))  
  {  
    connection.Open();  
    command.ExecuteNonQuery();  
  }  

アプリケーション ロールおよび接続プールApplication Roles and Connection Pooling

SQL ServerSQL Server システム ストアド プロシージャの呼び出しにより sp_setapprole のアプリケーション ロールがアクティブになった後は、その接続のセキュリティ コンテキストをリセットすることはできません。After a SQL ServerSQL Server application role has been activated by calling the sp_setapprole system stored procedure, the security context of that connection cannot be reset. ただし、プールを有効した場合は、プールに接続が返され、プール接続が再利用されると、エラーが発生します。However, if pooling is enabled, the connection is returned to the pool, and an error occurs when the pooled connection is reused. 詳細については、サポート技術情報の記事を参照してください"では、OLE DB リソース プールの SQL アプリケーション ロール エラー。"。For more information, see the Knowledge Base article, "SQL application role errors with OLE DB resource pooling."

アプリケーション ロールに代わる方法Application Role Alternatives

アプリケーション ロールに代わるセキュリティ メカニズムの使用をお勧めします。We recommend that you take advantage of security mechanisms that you can use instead of application roles. 詳細については、次を参照してください。 SQL Server でのアプリケーション ロールの作成です。For more information, see Creating Application Roles in SQL Server.

参照See Also

接続プールConnection Pooling
SQL Server と ADO.NETSQL Server and ADO.NET
パフォーマンス カウンターPerformance Counters
ADO.NET のマネージ プロバイダーと DataSet デベロッパー センターADO.NET Managed Providers and DataSet Developer Center