2008-08-27 15 views
98

Necesito detectar específicamente las excepciones de tiempo de espera del servidor SQL para que puedan manejarse de manera diferente. Sé que podría atrapar la SqlException y luego verificar si la cadena del mensaje contiene "Tiempo de espera" pero me preguntaba si existe una mejor manera de hacerlo.Cómo atrapar excepciones de tiempo de espera de SQLServer

try 
{ 
    //some code 
} 
catch (SqlException ex) 
{ 

    if (ex.Message.Contains("Timeout")) 
    { 
     //handle timeout 
    } 
    else 
    { 
     throw; 
    } 
} 
+0

¿Está buscando un ConnectionTimeout o una CommandTimeout, es decir, están esperando la conexión a un error o el comando ejecutado a fallar? – edosoft

+0

Estoy buscando un CommandTimeout, que se establece en un valor predeterminado de 30 segundos, creo – brodie

Respuesta

134

Para comprobar el tiempo de espera, creo que comprueba el valor de ex.Number. Si es -2, entonces tienes una situación de tiempo de espera.

-2 es el código de error para el tiempo de espera, devuelto por DBNETLIB, el controlador MDAC para SQL Server. Esto se puede ver descargando Reflector y buscando en System.Data.SqlClient.TdsEnums durante TIMEOUT_EXPIRED.

Su código sería el siguiente:

if (ex.Number == -2) 
{ 
    //handle timeout 
} 

Código para demostrar el fracaso:

try 
{ 
    SqlConnection sql = new SqlConnection(@"Network Library=DBMSSOCN;Data Source=YourServer,1433;Initial Catalog=YourDB;Integrated Security=SSPI;"); 
    sql.Open(); 

    SqlCommand cmd = sql.CreateCommand(); 
    cmd.CommandText = "DECLARE @i int WHILE EXISTS (SELECT 1 from sysobjects) BEGIN SELECT @i = 1 END"; 
    cmd.ExecuteNonQuery(); // This line will timeout. 

    cmd.Dispose(); 
    sql.Close(); 
} 
catch (SqlException ex) 
{ 
    if (ex.Number == -2) { 
     Console.WriteLine ("Timeout occurred"); 
    } 
} 
+0

Sí, eso es más o menos lo que estoy haciendo en este momento, pero no es muy elegante comprobar -2 – brodie

+11

Descargar Red Gate's Reflector, y buscar TIMEOUT_EXPIRED. Vive en System.Data.SqlClient.TdsEnums, y su valor es -2. : o) – Jonathan

+2

Para aquellos que no tienen acceso a Reflector: [link] (http://www.dotnetframework.org/default.aspx/[email protected]/[email protected]/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ ndp/fx/src/Data/System/Data/SqlClient/TdsEnums @ cs/1305376/TdsEnums @ cs) – ankitk

1

¿Cuál es el valor de la propiedad SqlException.ErrorCode? ¿Puedes trabajar con eso?

Al tener tiempos de espera, puede valer la pena verificar el código de -2146232060.

Lo configuraría como un const estático en su código de datos.

+2

En cuanto a los documentos de ErrorCode, me parece que está informando errores Interop-Level. Por lo tanto, puede ser más sobre el nivel de errores COM o que un proveedor encontró una excepción (generalmente) en lugar de un error específico relacionado con lo que está haciendo. –

+0

@Eric es correcto: es un código HRESULT para el tipo SqlException, no para el origen de la excepción. – codekaizen

11

aquí: http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.adonet/2006-10/msg00064.html

Usted puede leer también que Thomas Weingartner escribió:

Timeout: SqlException.Number == -2 (This is an ADO.NET error code)
General Network Error: SqlException.Number == 11
Deadlock: SqlException.Number == 1205 (This is an SQL Server error code)

...

We handle the "General Network Error" as a timeout exception too. It only occurs under rare circumstances e.g. when your update/insert/delete query will raise a long running trigger.

Cuestiones relacionadas