Как поймать исключения тайм-аута SQLServer

Мне нужно специально перехватывать исключения тайм-аута SQL-сервера, чтобы их можно было обрабатывать по-другому. Я знаю, что могу поймать SqlException, а затем проверить, содержит ли строка сообщения «Тайм-аут», но мне было интересно, есть ли лучший способ сделать это?

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

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

person brodie    schedule 27.08.2008    source источник
comment
Вы ищете ConnectionTimeout или CommandTimeout, т.е. ожидаете ли вы сбоя соединения или сбоя выполненной команды?   -  person edosoft    schedule 15.09.2008
comment
Я ищу CommandTimeout, для которого установлено значение по умолчанию 30 секунд, я думаю   -  person brodie    schedule 16.09.2008


Ответы (6)


Чтобы проверить тайм-аут, я полагаю, вы проверяете значение 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");
    }
}
person Jonathan    schedule 15.09.2008
comment
Да, это в основном то, что я делаю сейчас, но это не очень элегантная проверка на -2. - person brodie; 16.09.2008
comment
Загрузите Reflector Red Gate и найдите TIMEOUT_EXPIRED. Он находится в System.Data.SqlClient.TdsEnums и имеет значение -2. : o) - person Jonathan; 18.09.2008
comment
Для тех, у кого нет доступа к Reflector: ссылка - person ankitk; 14.11.2013
comment
@brodie Вот почему вы должны сделать для него константу, и вы можете объяснить, откуда взялось магическое значение, в комментарии к константе. - person Jason L.; 27.03.2017

здесь: http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.adonet/2006-10/msg00064.html

Вы также можете прочитать это Thomas Weingartner написал:

Тайм-аут: SqlException.Number == -2 (это код ошибки ADO.NET)
Общая сетевая ошибка: SqlException.Number == 11
Тупик: SqlException.Number == 1205 (это ошибка SQL Server код)

...

Мы обрабатываем «Общую ошибку сети» также как исключение тайм-аута. Это происходит только в редких случаях, например, когда ваш запрос на обновление / вставку / удаление вызовет длительный триггер.

person Roland Pihlakas    schedule 14.04.2013

Обновлено для C # 6:

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

Очень просто и приятно смотреть !!

person John Evans    schedule 11.02.2019
comment
Спасибо ... Мне нравится ваше предложение, и я использую его. - person Rubens; 19.02.2021

Какое значение имеет свойство SqlException.ErrorCode? Вы можете с этим работать?

Если есть тайм-ауты, возможно, стоит проверить код -2146232060.

Я бы установил это как статическую константу в вашем коде данных.

person Rob Cooper    schedule 27.08.2008
comment
Глядя на документы для ErrorCode, мне кажется, что он сообщает об ошибках уровня взаимодействия. Таким образом, это может быть больше на уровне ошибок COM или того, что провайдер обнаружил исключение (как правило), а не конкретную ошибку, связанную с тем, что вы делаете. - person Eric Tuttleman; 18.06.2010
comment
@Eric верен - это код HRESULT для типа SqlException, а не для источника исключения. - person codekaizen; 17.12.2011

Я не уверен, но когда у нас истекает время ожидания выполнения или время ожидания команды. Клиент отправляет «ABORT» на SQL Server, а затем просто прекращает обработку запроса. Ни одна транзакция не откатывается, блокировки не снимаются. чтобы решить эту проблему, я удаляю транзакцию в хранимой процедуре и использую транзакцию SQL в моем .Net-коде для управления sqlException

person hamid reza Heydari    schedule 30.10.2019

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

person Srinivas Pakalapati    schedule 13.11.2019
comment
Он не отвечает на вопрос, как поймать тайм-аут команды в коде С #. - person Jonathan; 13.11.2019