CommandTimeout para problemas de timeout na BD

2008-09-05

Um pequeno problema que resolvi hoje, que deve ser comum com alguns procedimentos pesados em bases de dados, é da própria base de dados lançar um timeout num procedimento. Para todos os efeitos, as bases de dados como SQL Server geralmente definem um período finito de tempo máximo para a ligação, de modo a evitar potenciais deadlocks ao sistema. O “erro” por timeout eleva uma excepção que no SQL Server 2005 é do tipo SQLException:

System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. at System.Data.SqlClient.SqlInternalConnection

Entre a base de dados e o .NET, há algumas formas em como podemos alterar o período máximo de execução. O primeiro é na própria base de dados, onde podemos alterar o valor pro defeito. No caso do SQL Server (Express 2005) o valor é de 600s. Se colocarmos o valor 0, o timeout é anulado e a base só termina quando finalizar o procedimento que tem em curso, o que pode ser perigoso.

Em termos de .NET e no caso de estar a utilizar a classe SQLCommand para enviar os comandos à base de dados, uma hipotese é na connection string usada para ligar à base de dados inserir um Connect Timeout do tipo:

Isto naturalmente impõe o tempo de timeout para todas as ligações efectuadas com a string, o que poderá ter ou não interesse. Se a alteração interessar apenas a um comando ou um conjunto restrito de comandos, será de todo o interesse estabelecer o timeout para apenas o comando em questão. Inicializando um SqlCommand sobre uma conecção, é possível definir o timeout:

É também importante notar que o Command Timeout é diferente de um Connection Timeout. Connection Timeout está ligado ao processo de tentativa de ligação, enquanto o Command Timeout está ligado ao procedimento em si, e o tempo que demora a completar. Definir o CommandTimeout resultou para o meu problema onde adicionei a linha de código com um tempo suficientemente alto (e definido no ficheiro de configuração).

Mais info pode ser encontrado em:
Forums.ASP.Net
CommandTimeout no MSDN
ConnectionTimeout no MSDN