Come intercettare le eccezioni di timeout di SQLServer
-
09-06-2019 - |
Domanda
È necessario rilevare in modo specifico le eccezioni di timeout del server SQL in modo che possano essere gestite in modo diverso.So che potrei rilevare SqlException e quindi verificare se la stringa del messaggio contiene "Timeout", ma mi chiedevo se esiste un modo migliore per farlo?
try
{
//some code
}
catch (SqlException ex)
{
if (ex.Message.Contains("Timeout"))
{
//handle timeout
}
else
{
throw;
}
}
Soluzione
Per verificare la presenza di un timeout, credo che tu controlli il valore di ex.Number.Se è -2, allora hai una situazione di timeout.
-2 è il codice di errore per il timeout, restituito da DBNETLIB, il driver MDAC per SQL Server.Questo può essere visto scaricando Riflettore, e cercando in System.Data.SqlClient.TdsEnums TIMEOUT_EXPIRED.
Il tuo codice direbbe:
if (ex.Number == -2)
{
//handle timeout
}
Codice per dimostrare il fallimento:
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");
}
}
Altri suggerimenti
Qui: http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.adonet/2006-10/msg00064.html
Puoi leggere anche quello Thomas Weingartner ha scritto:
Tempo scaduto:SqlException.Number == -2 (questo è un codice di errore ADO.NET)
Errore di rete generale:SqlException.Number == 11
Impasse:SqlException.Number == 1205 (questo è un codice di errore di SQL Server)
...
Gestiamo anche l'"Errore generale di rete" come un'eccezione di timeout.Si verifica solo in rare circostanze, ad es.quando la query di aggiornamento/inserimento/eliminazione genererà un trigger a lunga esecuzione.
Aggiornato per C# 6:
try
{
// some code
}
catch (SqlException ex) when (ex.Number == -2) // -2 is a sql timeout
{
// handle timeout
}
Molto semplice e bello da vedere!!
Qual è il valore della proprietà SqlException.ErrorCode?Puoi lavorarci?
Quando si verificano timeout, potrebbe valere la pena controllare il codice -2146232060.
Lo imposterei come const statico nel codice dati.