Pool de conexões do SQL Server (ADO.NET)SQL Server Connection Pooling (ADO.NET)

Para se conectar a um servidor de banco de dados, existem, normalmente, várias etapas demoradas.Connecting to a database server typically consists of several time-consuming steps. Um canal físico, como um soquete ou um pipe nomeado, deve ser estabelecido, o handshake inicial com o servidor deve ocorrer, informações de cadeia de conexão devem ser analisadas, a conexão deve ser autenticada pelo servidor, verificações devem ser realizadas para a inscrição na transação atual e assim por diante.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.

Na prática, a maioria dos aplicativos usa apenas uma ou algumas configurações diferentes para conexões.In practice, most applications use only one or a few different configurations for connections. Isso significa que, durante a execução do aplicativo, muitas conexões idênticas serão abertas e fechadas repetidamente.This means that during application execution, many identical connections will be repeatedly opened and closed. Para minimizar o custo de abertura de conexões, o ADO.NET usa uma técnica de otimização chamada pooling de conexão.To minimize the cost of opening connections, ADO.NET uses an optimization technique called connection pooling.

O pool de conexões reduz o número de vezes que as novas conexões devem ser abertas.Connection pooling reduces the number of times that new connections must be opened. O Pooler mantém a propriedade da conexão física.The pooler maintains ownership of the physical connection. Para gerenciar as conexões, ele mantém um conjunto de conexões ativas para cada configuração de conexão específica.It manages connections by keeping alive a set of active connections for each given connection configuration. Sempre que um usuário chama Open em uma conexão, o pooler procura uma conexão disponível no pool.Whenever a user calls Open on a connection, the pooler looks for an available connection in the pool. Se houver uma conexão agrupada disponível, ele retornará essa conexão para o chamador, em vez de abrir uma nova conexão.If a pooled connection is available, it returns it to the caller instead of opening a new connection. Quando o aplicativo chama Close na conexão, o pooler retorna essa chamada para o conjunto de conexões ativas agrupadas, em vez de fechar a conexão.When the application calls Close on the connection, the pooler returns it to the pooled set of active connections instead of closing it. Depois de retornada ao pool, a conexão está pronta para ser reutilizada na próxima chamada Open.Once the connection is returned to the pool, it is ready to be reused on the next Open call.

Somente conexões com a mesma configuração podem ser agrupadas.Only connections with the same configuration can be pooled. O ADO.NET mantém vários pools ao mesmo tempo, um para cada configuração.ADO.NET keeps several pools at the same time, one for each configuration. As conexões são separadas em pools pela cadeia de conexão e, quando o modo de segurança integrada é usado, pela identidade do Windows.Connections are separated into pools by connection string, and by Windows identity when integrated security is used. As conexões também são agrupadas conforme estejam ou não inscritas em uma transação.Connections are also pooled based on whether they are enlisted in a transaction. Ao usar o ChangePassword, a instância SqlCredential afeta o pool de conexões.When using ChangePassword, the SqlCredential instance affects the connection pool. As instâncias diferentes de SqlCredential usarão pools de conexões diferentes, mesmo se a identificação do usuário e a senha forem iguais.Different instances of SqlCredential will use different connection pools, even if the user ID and password are the same.

O pooling de conexões pode melhorar significativamente o desempenho e a escalabilidade do aplicativo.Pooling connections can significantly enhance the performance and scalability of your application. Por padrão, o pool de conexões está habilitado em ADO.NET.By default, connection pooling is enabled in ADO.NET. A menos que você explicitamente o desabilite, o pooler otimiza as conexões quando elas são abertas e fechadas no aplicativo.Unless you explicitly disable it, the pooler optimizes the connections as they are opened and closed in your application. Você também pode fornecer vários modificadores de cadeias de conexão para controlar o comportamento do pool de conexões.You can also supply several connection string modifiers to control connection pooling behavior. Para obter mais informações, consulte "Controlando o pool de conexões com palavras-chave de cadeias de conexão" posteriormente neste tópico.For more information, see "Controlling Connection Pooling with Connection String Keywords" later in this topic.

Observação

Quando o pool de conexões é habilitado e ocorre um erro de tempo limite ou outro erro de logon, é gerada uma exceção e as tentativas subsequentes de conexão falham nos próximos cinco segundos, "o período bloqueio".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". Se o aplicativo tentar se conectar dentro do período de bloqueio, a primeira exceção será gerada novamente.If the application attempts to connect within the blocking period, the first exception will be thrown again. Falhas subsequentes após o término do período de bloqueio resultarão em novos períodos de bloqueio, duas vezes maior que o anterior, até um máximo de um minuto.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.

Criação e atribuição de poolsPool Creation and Assignment

Quando uma conexão é aberta pela primeira vez, um pool de conexões é criado com base em um algoritmo compatível exato que associa o pool à cadeia de conexão na conexão.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. Cada pool de conexões é associado a uma cadeia de conexão distinta.Each connection pool is associated with a distinct connection string. Se a cadeia de conexão não for uma correspondência exata de um pool existente, quando uma nova conexão for aberta, um novo pool será criado.When a new connection is opened, if the connection string is not an exact match to an existing pool, a new pool is created. As conexões são agrupadas por processo, por domínio do aplicativo, por cadeia de conexão e, quando o modo de segurança integrada é usado, pela identidade do Windows.Connections are pooled per process, per application domain, per connection string and when integrated security is used, per Windows identity. As cadeias de conexão também devem ser uma correspondência exata; as palavras-chave fornecidas em uma ordem diferente para a mesma conexão serão agrupadas separadamente.Connection strings must also be an exact match; keywords supplied in a different order for the same connection will be pooled separately.

No exemplo de C# a seguir, três novos objetos SqlConnection são criados, mas apenas dois pools de conexões são necessários para gerenciá-los.In the following C# example, three new SqlConnection objects are created, but only two connection pools are required to manage them. Observe que a primeira e a segunda cadeias de conexão diferem pelo valor atribuído para 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.  
    }  

Se MinPoolSize não for especificado na cadeia de conexão, nem estiver especificado como zero, as conexões no pool serão fechadas após um período de inatividade.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. Entretanto, se o MinPoolSize especificado for maior que zero, o pool de conexões não será destruído até que o AppDomain seja descarregado e o processo concluído.However, if the specified MinPoolSize is greater than zero, the connection pool is not destroyed until the AppDomain is unloaded and the process ends. A manutenção de pools inativos ou vazios envolve sobrecarga mínima do sistema.Maintenance of inactive or empty pools involves minimal system overhead.

Observação

O pool é limpo automaticamente quando ocorre um erro fatal, como um failover.The pool is automatically cleared when a fatal error occurs, such as a failover.

Adicionando conexõesAdding Connections

Um pool de conexões é criado para cada cadeia de conexão exclusiva.A connection pool is created for each unique connection string. Quando um pool é criado, vários objetos de conexão são criados e adicionados ao pool para que o requisito de tamanho mínimo de pool seja atendido.When a pool is created, multiple connection objects are created and added to the pool so that the minimum pool size requirement is satisfied. As conexões são adicionadas ao pool quando necessário, até o tamanho máximo de pool especificado (100 é o padrão).Connections are added to the pool as needed, up to the maximum pool size specified (100 is the default). As conexões são retornadas para o pool quando fechadas ou descartadas.Connections are released back into the pool when they are closed or disposed.

Quando um objeto SqlConnection é solicitado, ele é obtido do pool caso haja uma conexão útil disponível.When a SqlConnection object is requested, it is obtained from the pool if a usable connection is available. Para ser útil, uma conexão não deve estar em uso, deve ter um contexto de transação correspondente (ou não deve estar associada a nenhum contexto de transação) e deve ter um vínculo válido com o servidor.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.

O pool de conexões atende às solicitações de conexões realocando-as à medida que são retornadas ao pool.The connection pooler satisfies requests for connections by reallocating connections as they are released back into the pool. Se o tamanho máximo de pool for atingido e nenhuma conexão útil estiver disponível, a solicitação será colocada na fila.If the maximum pool size has been reached and no usable connection is available, the request is queued. Em seguida, o pooler tentará recuperar conexões até que o tempo limite seja esgotado (o padrão é de 15 segundos).The pooler then tries to reclaim any connections until the time-out is reached (the default is 15 seconds). Se o pooler não puder atender à solicitação antes que se esgote o tempo limite de conexão, uma exceção será gerada.If the pooler cannot satisfy the request before the connection times out, an exception is thrown.

Cuidado

É altamente recomendável sempre fechar a conexão quando você terminar de usá-la para que a conexão seja retornada ao pool.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. Você pode fazer isso usando os Close métodos ou Dispose do Connection objeto ou abrindo todas as conexões dentro de uma using instrução no C#, ou uma Using instrução em Visual 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 Basic. As conexões que não são fechadas explicitamente não podem ser adicionadas nem retornadas ao pool.Connections that are not explicitly closed might not be added or returned to the pool. Para obter mais informações, consulte usando a instrução ou como: Descarte de um recurso do sistema para Visual Basic.For more information, see using Statement or How to: Dispose of a System Resource for Visual Basic.

Observação

Não chame Close nem Dispose em um objeto Connection, em um DataReader nem em nenhum outro objeto gerenciado no método Finalize de sua classe.Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. Em um finalizador, libere somente recursos não gerenciados que sua classe possui diretamente.In a finalizer, only release unmanaged resources that your class owns directly. Se a classe não tiver nenhum recurso não gerenciado, não inclua um método Finalize em sua definição de classe.If your class does not own any unmanaged resources, do not include a Finalize method in your class definition. Para obter mais informações, consulte coleta de lixo.For more information, see Garbage Collection.

Para obter mais informações sobre os eventos associados às conexões de abertura e fechamento, consulte classe de evento Audit login e auditoria logout Event na documentação do SQL Server.For more info about the events associated with opening and closing connections, see Audit Login Event Class and Audit Logout Event Class in the SQL Server documentation.

Removendo conexõesRemoving Connections

O pool de conexões remove uma conexão do pool após ele ficar ocioso por aproximadamente 4-8 minutos, ou se o Pooler detectar que a conexão com o servidor foi severa.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. Observe que uma conexão interrompida pode ser detectada somente após uma tentativa de comunicação com o servidor.Note that a severed connection can be detected only after attempting to communicate with the server. Se for encontrada uma conexão que não esteja mais conectada ao servidor, ela será marcada como inválida.If a connection is found that is no longer connected to the server, it is marked as invalid. As conexões inválidas são removidas de pool de conexões somente quando são fechadas ou recuperadas.Invalid connections are removed from the connection pool only when they are closed or reclaimed.

Se uma conexão com um servidor desapareceu, ela pode ser removida do pool mesmo se o pooler de conexões não tiver detectado a conexão interrompida e a marcado como inválida.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. Este é o caso porque a sobrecarga de verificar se a conexão ainda é válida eliminaria os benefícios de se ter um pooler, provocando outra viagem de ida e volta ao servidor.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. Quando isso ocorrer, a primeira tentativa de usar a conexão detectará que a conexão foi interrompida e uma exceção será gerada.When this occurs, the first attempt to use the connection will detect that the connection has been severed, and an exception is thrown.

Limpando o poolClearing the Pool

O ADO.NET 2,0 introduziu dois novos métodos para limpar o ClearAllPools pool ClearPool: e.ADO.NET 2.0 introduced two new methods to clear the pool: ClearAllPools and ClearPool. ClearAllPools limpa os pools de conexões de um provedor específico e ClearPool limpa o pool de conexões associado a uma conexão específica.ClearAllPools clears the connection pools for a given provider, and ClearPool clears the connection pool that is associated with a specific connection. Se houver conexões em uso no momento da chamada, elas serão devidamente marcadas.If there are connections being used at the time of the call, they are marked appropriately. Quando fechadas, serão descartadas, em vez de retornadas ao pool.When they are closed, they are discarded instead of being returned to the pool.

Suporte a transaçõesTransaction Support

As conexões são removidas do pool e atribuídas com base no contexto de transação.Connections are drawn from the pool and assigned based on transaction context. A menos que Enlist=false seja especificado na cadeia de conexão, o pool de conexões verifica se a conexão está inscrita no contexto de Current.Unless Enlist=false is specified in the connection string, the connection pool makes sure that the connection is enlisted in the Current context. Quando uma conexão é fechada e retornada ao pool com uma transação System.Transactions inscrita, ela é reservada para que a próxima solicitação desse pool de conexões com a mesma transação System.Transactions seja retornada à mesma conexão, se disponível.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. Se uma solicitação desse tipo for emitida, e não houver conexões agrupadas disponíveis, uma conexão será removida da parte não transacionada do pool e depois inscrita.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. Se não houver conexões disponíveis em nenhuma área do pool, uma nova conexão será criada e inscrita.If no connections are available in either area of the pool, a new connection is created and enlisted.

Quando uma conexão for fechada, ela será retornada ao pool e à subdivisão apropriada com base no contexto de transação.When a connection is closed, it is released back into the pool and into the appropriate subdivision based on its transaction context. Portanto, é possível fechar a conexão sem gerar erros, mesmo que uma transação distribuída ainda esteja pendente.Therefore, you can close the connection without generating an error, even though a distributed transaction is still pending. Isso permite confirmar ou anular a transação distribuída posteriormente.This allows you to commit or abort the distributed transaction later.

Controlando o pool de conexões com palavras-chave de cadeias de conexãoControlling Connection Pooling with Connection String Keywords

A propriedade ConnectionString do objeto SqlConnection dá suporte a pares chave-valor de cadeias de conexão que podem ser usados para ajustar o comportamento da lógica do pool de conexões.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. Para obter mais informações, consulte ConnectionString.For more information, see ConnectionString.

Fragmentação de poolPool Fragmentation

A fragmentação de pool é um problema comum em muitos aplicativos da Web nos quais o aplicativo pode criar um grande número de pools que não são liberados até que o processo seja encerrado.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. Isso deixa um grande número de conexões abertas e consumindo memória, o que resulta em baixo desempenho.This leaves a large number of connections open and consuming memory, which results in poor performance.

Fragmentação de pool devido à segurança integradaPool Fragmentation Due to Integrated Security

As conexões são agrupadas de acordo com a cadeia de conexão e a identidade do usuário.Connections are pooled according to the connection string plus the user identity. Portanto, se você usa autenticação Básica ou autenticação do Windows no site, bem como um logon de segurança integrada, pode obter um pool por usuário.Therefore, if you use Basic authentication or Windows Authentication on the Web site and an integrated security login, you get one pool per user. Embora isso melhore o desempenho de solicitações de bancos de dados subsequentes feitas por um único usuário, esse usuário não pode aproveitar as vantagens das conexões feitas por outros usuários.Although this improves the performance of subsequent database requests for a single user, that user cannot take advantage of connections made by other users. Isso também resulta em, pelo menos, uma conexão por usuário com o servidor de banco de dados.It also results in at least one connection per user to the database server. Trata-se de um efeito colateral de uma arquitetura de aplicativo Web específico que os desenvolvedores devem ponderar em relação aos requisitos de segurança e auditoria.This is a side effect of a particular Web application architecture that developers must weigh against security and auditing requirements.

Fragmentação de pool devido a vários bancos de dadosPool Fragmentation Due to Many Databases

Vários provedores de serviços de Internet hospedam vários sites em um único servidor.Many Internet service providers host several Web sites on a single server. Eles podem usar um único banco de dados para confirmar um logon de autenticação de formulários e para abrir uma conexão com um banco de dados específico desse usuário ou grupo de usuários.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. A conexão com o banco de dados de autenticação é agrupada e usada por todos.The connection to the authentication database is pooled and used by everyone. Entretanto, há um pool de conexões separado para cada banco de dados, que aumenta o número de conexões com o servidor.However, there is a separate pool of connections to each database, which increase the number of connections to the server.

Trata-se também de um efeito colateral de projeto do aplicativo.This is also a side-effect of the application design. Existe uma forma relativamente simples de evitar esse efeito colateral sem comprometer a segurança quando você se conectar ao SQL Server.There is a relatively simple way to avoid this side effect without compromising security when you connect to SQL Server. Em vez de se conectar a um banco de dados separado para cada usuário ou grupo, conecte-se ao mesmo banco de dados no servidor e execute a instrução Transact-SQL USE para alternar para o banco de dados desejado.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-SQL USE statement to change to the desired database. O fragmento de código a seguir demonstra como criar uma conexão inicial com o banco de dados master e depois alternar para o banco de dados desejado especificado na variável da cadeia de caracteres 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();  
  }  

Funções de aplicativo e pool de conexõesApplication Roles and Connection Pooling

Depois de ativada uma função de aplicativo do SQL Server ao chamar o procedimento armazenado do sistema sp_setapprole, o contexto de segurança dessa conexão não pode ser redefinido.After a SQL Server application role has been activated by calling the sp_setapprole system stored procedure, the security context of that connection cannot be reset. Entretanto, se o pool estiver habilitado, a conexão será retornada a ele e ocorrerá um erro quando a conexão agrupada for reutilizada.However, if pooling is enabled, the connection is returned to the pool, and an error occurs when the pooled connection is reused. Para obter mais informações, consulte o artigo da base de dados de conhecimento, "erros de função de aplicativo SQL com OLE DB pooling de recursos".For more information, see the Knowledge Base article, "SQL application role errors with OLE DB resource pooling."

Alternativas a funções de aplicativoApplication Role Alternatives

Recomendamos que você aproveite todas as vantagens dos mecanismos de segurança que podem ser usados no lugar de funções de aplicativo.We recommend that you take advantage of security mechanisms that you can use instead of application roles. Para obter mais informações, consulte criando funções de aplicativo no SQL Server.For more information, see Creating Application Roles in SQL Server.

Consulte tambémSee also