128 votes

Comment attraper les exceptions de timeout de SQLServer ?

J'ai besoin d'attraper spécifiquement les exceptions de timeout du serveur SQL pour qu'elles puissent être traitées différemment. Je sais que je pourrais attraper l'exception SqlException et ensuite vérifier si la chaîne de message contient "Timeout", mais je me demandais s'il y avait une meilleure façon de le faire ?

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

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

0 votes

Recherchez-vous un ConnectionTimeout ou un CommandTimeout, c'est-à-dire attendez-vous que la connexion échoue ou que la commande exécutée échoue ?

0 votes

Je cherche un CommandTimeout, qui est réglé par défaut à 30 secondes je pense.

172voto

Jonathan Points 6934

Pour vérifier l'existence d'un délai d'attente, je crois qu'il faut vérifier la valeur de ex.Number. Si elle est égale à -2, alors vous avez une situation de timeout.

-2 est le code d'erreur pour le timeout, renvoyé par DBNETLIB, le pilote MDAC pour SQL Server. Vous pouvez le voir en téléchargeant Réflecteur et en cherchant sous System.Data.SqlClient.TdsEnums pour TIMEOUT_EXPIRED.

Votre code serait le suivant :

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 votes

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

12 votes

Téléchargez Red Gate's Reflector, et cherchez TIMEOUT_EXPIRED. Il se trouve dans System.Data.SqlClient.TdsEnums, et sa valeur est -2. :o)

2 votes

Pour ceux qui n'ont pas accès à Reflector : enlace

23voto

Roland Pihlakas Points 583

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

Vous pouvez également lire que Thomas Weingartner écrit :

Temps mort : SqlException.Number == -2 (C'est un code d'erreur ADO.NET)
Erreur générale de réseau : SqlException.Nombre == 11
Impasse : SqlException.Number == 1205 (C'est un code d'erreur du serveur SQL)

...

Nous traitons également l'"erreur générale de réseau" comme une exception de délai d'attente. Cela ne se produit que dans de rares circonstances, par exemple lorsque votre requête de mise à jour/insertion/suppression déclenche un déclencheur de longue durée.

17voto

John Evans Points 143

Mise à jour pour c# 6 :

    try
    {
        // some code
    }
    catch (SqlException ex) when (ex.Number == -2)  // -2 is a sql timeout
    {
        // handle timeout
    }

Très simple et agréable à regarder !

0voto

Je ne suis pas sûr mais quand nous avons un temps mort d'exécution ou de commande. Le client envoie un "ABORT" à SQL Server puis abandonne simplement le traitement de la requête. Aucune transaction n'est annulée, aucun verrou n'est libéré. Pour résoudre ce problème, je supprime la transaction dans la procédure stockée et j'utilise la transaction SQL dans mon code .Net pour gérer les exceptions sqlException.

0voto

Rob Cooper Points 15945

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

Lorsqu'il y a des délais d'attente, il peut être utile de vérifier le code pour les éléments suivants -2146232060 .

Je le configurerais comme une constante statique dans votre code de données.

2 votes

En regardant les documents relatifs à ErrorCode, il me semble qu'il signale les erreurs de niveau interopérationnel. Il se peut donc qu'il s'agisse plutôt d'erreurs COM ou qu'un fournisseur ait rencontré une exception (en général) plutôt que d'une erreur spécifique liée à ce que vous faites.

0 votes

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X