2008-08-27 5 views
98

Ich muss SQL Server-Timeout-Ausnahmen speziell abfangen, damit sie unterschiedlich behandelt werden können. Ich weiß, ich konnte die SqlException abfangen und dann überprüfen, ob die Nachrichtenzeichenfolge "Timeout" enthält, aber fragte sich, ob es eine bessere Möglichkeit gibt, es zu tun?So fangen Sie SQL Server-Zeitüberschreitungsausnahmen ab

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

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

Suchen Sie eine Connection oder ein Command, also werden Sie die Verbindung erwartet auszufallen oder den ausgeführten Befehl zum Scheitern verurteilt? – edosoft

+0

Ich bin auf der Suche nach einem CommandTimeout, das auf einen Standardwert von 30 Sekunden eingestellt ist, denke ich – brodie

Antwort

134

Um nach einem Timeout zu suchen, glaube ich, dass Sie den Wert von ex.Number überprüfen. Wenn es -2 ist, dann haben Sie eine Timeout-Situation.

-2 ist der Fehlercode für Timeout, der von DBNETLIB, dem MDAC-Treiber für SQL Server zurückgegeben wird. Dies wird angezeigt, indem Sie Reflector herunterladen und unter System.Data.SqlClient.TdsEnums nach TIMEOUT_EXPIRED suchen.

würde Ihr Code lesen:

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

-Code Versagen zu demonstrieren:

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

Ja, das ist ziemlich genau das, was ich gerade mache, aber es ist nicht sehr elegant, nach -2 – brodie

+11

zu suchen. Lade den Reflektor von Red Gate herunter und suche nach TIMEOUT_EXPIRED. Es befindet sich in System.Data.SqlClient.TdsEnums, und sein Wert ist -2. : o) – Jonathan

+2

Für diejenigen, die keinen Zugriff auf Reflector haben: [link] (http://www.dotnetframework.org/default.aspx/[email protected]/[email protected]/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ ndp/fx/src/Daten/System/Daten/SqlClient/TdsEnums @ cs/1305376/TdsEnums @ cs) – ankitk

1

Wie ist der Wert für die SqlException.ErrorCode-Eigenschaft? Kannst du damit arbeiten?

Bei Timeouts kann es sich lohnen, den Code für -2146232060 zu überprüfen.

Ich würde dies als eine statische const in Ihrem Datencode einrichten.

+2

Mit Blick auf die Dokumentation für ErrorCode scheint es mir, dass es Interop-Level-Fehler meldet. Es könnte also mehr auf der Ebene von COM-Fehlern liegen oder dass ein Provider (allgemein) eine Ausnahme anstelle eines spezifischen Fehlers in Bezug auf das, was Sie gerade tun, entdeckt hat. –

+0

@Eric ist korrekt - das ist ein HRESULT-Code für den SqlException-Typ, nicht für die Quelle der Ausnahme. – codekaizen

11

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

Sie auch, dass Thomas Weingärtner schrieb lesen:


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.