ADO.NET: Error Message: Timeout expired. The timeout period elapsed prior to obtaining a connection
- Siltech Consult
- 7 de out. de 2019
- 2 min de leitura
Problema: Error Message: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
O erro que apresentado acima geralmente é causado por estouro de conexões do ADO.NET.
Existem alguns parametros usados para controlar o Connection Pooling que são:
Connection Timeout: Controla o tempo de espera in segundos em que uma conexão é requisitada. Se o tempo de timeout expirar este erro acima é apresentado. O Default é 15 segundos;
Max Pool Size: Especifica o tamanho máximo do connection pool. O default é 100. Porém, o uso ou não do valor default vai depender do tempo médio que as conexões com o banco demorarem para ser concluídas.
Min Pool Size: Número inicial de conexões que são adicionadas quando o pool é criado. O default é 0. No entanto, nunca é o valor recomendado para a maioria das aplicações. Alterando para 5, toda vez que uma chamada for iniciada a mesma não irá precisar requisitar nova conexão no banco.
Pooling: Habilita ou não o pooling. Pode ser on ou off. Default é on.
O que está ocorrendo é que estes valores default (ou os que estão sendo usados) não estão sendo suficientes, provavelmente pelo processo de abertura/uso/fechamento das conexões não estar sendo gerenciado da forma correta, principalmente por falta de close no mesmo.
No exemplo abaixo:
SqlConnection conn = new SqlConnection(ConnString);
conn.Open();
FacaAlgumaCoisa();
conn.Close();
Embora tenha um CLOSE no final da função, caso exista alguma exception no FacaAlgumaCoisa() o cliente terá um erro da aplicação a aplicação será fechada porém a conexão não.
No próximo exemplo não teríamos este problema:
SqlConnection conn = new SqlConnection(ConnString);
try
{ onn.Open();
FacaAlgumaCoisa(conn);
}
finally
{ onn.Close();
}
SOLUÇÃO: Geralmente as recomendações são as seguintes:
1) Se o uso for associado com SqlDataReader e deve ser fechado quando o DataReader for fechado, façam uso com CommandBehavior.CloseConnection;
2) Feche a conexão explicitamente quando a mesma tiver que ser encerrada: sc.Close();
3) Usem a conexão em um Block, isso garante que quando o bloco for encerrado a conexão também será fechada. Eu recomendo esta opção. Por exemplo:
for (int i = 0; i < 50; i++)
{
using (SqlConnection sc = new SqlConnection(connString))
{
SqlCommand sCmd = new SqlCommand(“SELECT * FROM TABELAS”, sc);
sc.Open();
Console.WriteLine(“Conns Abertas” + i.ToString());
SqlDataReader sdr = sCmd.ExecuteReader();
sdr.Close();
}
}
4) Verifiquem quais valores estão sendo usados no connString para o pooling.
Dependendo da situação pode ser necessário aumentar o max pool size, setar um valor diferente de 0 para min pool size ou então aumentar o valor de connection timeout. Isso é feito no connString. Porém, esta solução pode ser apenas `paliativa` caso o problema seja o uso dos closes. Recomendo o uso do ítem 3.
Dúvidas? silverio@siltechconsult.com.br

Comentários