Як зловити винятки з тайм-ауту SQLServer


117

Мені потрібно спеціально вилучити винятки таймауту на сервері SQL, щоб з ними можна було по-різному оброблятись. Я знаю, що міг би зловити SqlException, а потім перевірити, чи містить рядок повідомлення "Timeout", але мені було цікаво, чи є кращий спосіб це зробити?

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

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

Шукаєте ви ConnectionTimeout або CommandTimeout, тобто очікуєте, що з'єднання не вдасться або виконана команда вийде з ладу?
edosoft

Я шукаю CommandTimeout, який встановлений за замовчуванням 30 секунд, я думаю
brodie

Відповіді:


157

Щоб перевірити час очікування, я вважаю, що ви перевіряєте значення ex.Number. Якщо він дорівнює -2, то у вас є ситуація в очікуванні.

-2 - код помилки на час очікування, повернутий з DBNETLIB, драйвера MDAC для SQL Server. Це можна побачити, завантаживши Reflector та переглянувши розділ System.Data.SqlClient.TdsEnums для TIMEOUT_EXPIRED.

Ваш код буде читати:

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

Код для демонстрації невдачі:

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");
    }
}

Так, це майже все, що я роблю на даний момент, але це не дуже елегантно перевірка на -2
brodie

12
Завантажте Рефлектор Red Gate та знайдіть TIMEOUT_EXPIRED. Він живе в System.Data.SqlClient.TdsEnums, а його значення - -2. : o)
Джонатан

2
Для тих, хто не має доступу до Reflector: посилання
ankitk

4
@brodie Ось чому ви повинні зробити константу для цього, і ви можете пояснити, звідки взялося "магічне" значення в коментарі до константи.
Джейсон Л.

18

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

Ви також можете прочитати, що Томас Вайнгартнер написав:

Час очікування: SqlException.Number == -2 (Це код помилки ADO.NET)
Загальна помилка в мережі: SqlException.Number == 11
Тупик: SqlException.Number == 1205 (Це код помилки SQL Server)

...

Ми також обробляємо "Загальну помилку в мережі" як виняток у режимі очікування. Це відбувається лише за рідкісних обставин, наприклад, коли ваш запит на оновлення / вставлення / видалення підніме тривалий тригер.


6

Оновлено для c # 6:

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

Дуже просто і приємно дивитися !!


0

Яке значення властивості SqlException.ErrorCode? Ви можете з цим працювати?

Якщо у вас є тайм-аути, можливо, варто перевірити код на -2146232060 .

Я б встановив це як статичний const у вашому коді даних.


2
Переглядаючи документи для ErrorCode, мені здається, що він повідомляє про помилки на рівні Interop. Тож може бути більше на рівні помилок COM або провайдер зіткнувся з винятком (як правило) замість конкретної помилки, що стосується того, що ви робите.
Ерік Тутлман

@Eric правильна - це код HRESULT для типу SqlException, а не джерело винятку.
codekaizen

0

Я не впевнений, але коли ми виконаємо тайм-аут або час виходу команди, клієнт відправляє "ABORT" на SQL Server, а потім просто відмовляється від обробки запитів. Жодна транзакція не відкочується, блокування не випускається. щоб вирішити цю проблему, я видаляю транзакцію в Stored-процедурі і використовую SQL-транзакцію в моєму коді .Net для управління sqlException


-2

Коли клієнт надсилає ABORT, жодні транзакції не повертаються назад. Щоб уникнути такої поведінки, ми повинні використовувати SET_XACT_ABORT ON https://docs.microsoft.com/en-us/sql/t-sql/statements/set-xact-abort-transact-sql?view=sql-server-ver15


1
Він не відповідає на питання про те, як
Джонатан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.