2008-08-27 21 views
98

Je dois spécifiquement intercepter les exceptions de délai d'expiration du serveur SQL afin qu'elles puissent être traitées différemment. Je sais que je pourrais attraper le SqlException et ensuite vérifier si la chaîne de message contient "Timeout", mais se demandait s'il y avait une meilleure façon de le faire?Comment intercepter les exceptions de dépassement de délai SQLServer

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

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

Vous cherchez un ConnectionTimeout ou un CommandTimeout, ce que vous attendez la connexion à l'échec ou la commande exécutée à l'échec? – edosoft

+0

Je suis à la recherche d'un CommandTimeout, qui est réglé sur une valeur par défaut de 30 secondes, je pense – brodie

Répondre

134

Pour vérifier un délai d'attente, je crois que vous vérifiez la valeur de ex.Number. Si c'est -2, alors vous avez une situation de temporisation.

-2 est le code d'erreur du délai d'attente renvoyé par DBNETLIB, le pilote MDAC pour SQL Server. Cela peut être vu en téléchargeant Reflector, et en regardant sous System.Data.SqlClient.TdsEnums pour TIMEOUT_EXPIRED.

Votre code serait:

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

pour démontrer l'échec:

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

Oui, c'est à peu près ce que je fais en ce moment, mais ce n'est pas très élégant vérifier pour -2 – brodie

+11

Télécharger Red Gate's Reflector, et rechercher TIMEOUT_EXPIRED. Il réside dans System.Data.SqlClient.TdsEnums et sa valeur est -2. : o) – Jonathan

+2

Pour ceux qui n'ont pas accès à 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

Quelle est la valeur de la propriété SqlException.ErrorCode? Pouvez-vous travailler avec ça?

En cas de dépassement de délai, il peut être utile de vérifier le code pour -2146232060. Je voudrais mettre cela en place comme const statique dans votre code de données.

+2

En regardant les documents pour ErrorCode, il me semble qu'il signale des erreurs de niveau Interop. Cela peut donc être plus au niveau des erreurs COM ou qu'un fournisseur a rencontré une exception (généralement) au lieu d'une erreur spécifique liée à ce que vous faites. –

+0

@Eric est correct - c'est un code HRESULT pour le type SqlException, pas pour la source de l'exception. – codekaizen

11

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

Vous pouvez lire aussi que Thomas Weingartner a écrit:

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.

Questions connexes