MSSQLSERVER_3617

Применимо к:SQL Server

Сведения

Атрибут значение
Название продукта SQL Server
Идентификатор события 3617
Источник событий MSSQLSERVER
Компонент SQLEngine
Символическое имя SYS_ATTN
Текст сообщения

Пояснение

Ошибка 3617 возникает, когда приложение или пользователь отменяет выполняющийся сейчас запрос либо когда подключение прерывается. Отмена запроса из приложения вызывает событие Attention в ядре СУБД. Событие "Внимание" — это событие SQL Server, которое регистрирует запрос клиентского приложения для завершения выполнения запроса. Вы можете отслеживать событие "Внимание" на стороне SQL Server с помощью класса расширенных событий или класса событий внимания трассировки SQL. Внутри системы события Attention отображаются как ошибка 3617.

Внимание (отмена запросов) является одним из наиболее распространенных событий TDS, обрабатываемых SQL Server. Когда приходит такой запрос, для сеанса и запроса задается соответствующий бит. Этот бит сканируется и учитывается по мере обработки сеансом точек приостановки. Некоторые дополнительные сведения о событиях Attention и их взаимодействии с другими компонентами см. в статье Tasks, Workers, Threads, Scheduler, Sessions, Connections, Requests ; what does it all mean? (Задачи, рабочие потоки, потоки, планировщик, сеансы, подключения, запросы: что все это означает?)

Действие пользователя

Краткий анализ причин:

  • Проверьте, что запросы выполняются за ожидаемое время (меньше настроенного значения времени ожидания запроса).
  • Увеличьте время ожидания запроса или команды.
  • Выясните, не отменяли ли пользователи выполнение запроса вручную.
  • Выясните, не произошло ли неожиданное завершение работы в приложении или ОС.

Проверьте, что запросы выполняются за ожидаемое время (меньше настроенного значения времени ожидания запроса). Самая частая причина событий Attention — это автоматическое завершение запросов приложением из-за превышения значений времени ожидания. Если значение времени ожидания запроса или команды равно 30 секундам и за это время запрос не возвращает клиентскому приложению ни одного пакета данных, то приложение отменяет запрос. В таких случаях имеет смысл проанализировать, почему запрос занимает столько времени, и принять меры по его ускорению.

Увеличьте время ожидания запроса или команды. Если определено, что отмененный запрос выполняется в пределах заданного базового срока, но все равно возникает превышение времени ожидания команды, то попробуйте увеличить значение времени в приложении базы данных.

Выясните, не отменяли ли пользователи выполнение запроса вручную. В некоторых случаях событие Attention может возникать просто из-за отмены запроса пользователем. В таких ситуациях рекомендуется спросить пользователей, не ожидали ли они более быстрого выполнения запроса, и либо оптимизировать запрос, либо указать базовое ожидаемое время в документации.

Выясните, не произошло ли неожиданное завершение запроса или подключения приложением или ОС либо же завершение работы самого приложения. Проанализируйте, что происходит на стороне приложения. Попробуйте посмотреть журналы приложений или системные журналы, чтобы определить первопричину.

Attention и транзакции

Как правило, события Attention возникают, когда время ожидания запроса в приложении истекает и приложение отменяет запрос. При возникновении события внимания SQL Server не автоматически откатывает открытые транзакции. Откат транзакции является обязанностью приложения, и для него есть два стандартных способа:

  • Контроль отката транзакций путем включения set XACT_ABORT ON при подключении к SQL Server. Если приложение этого не делает, возникнет потерянная транзакция.

  • Чаще для обработки ошибок приложения используют try.. catch... finally. В блоке try транзакция открывается, и если возникает ошибка, в блоке catch или finally выполняется ее откат.

Пример:


using (SqlConnection connection = new SqlConnection(sqlConnectionString))
{
    SqlTransaction transaction;
    SqlCommand command = connection.CreateCommand();

    connection.Open();
    transaction = connection.BeginTransaction("UpdateTran_Routine1");


    command.Connection = connection;
    command.Transaction = transaction;


    try
    {
        //update one of the tables 
        command.CommandText = "update dl_tab1 set col1 = 987";
        command.ExecuteNonQuery();
        transaction.Commit();
    }

    catch (SqlException ex)
    {
        // Attempt to roll back the transaction.
        try
        {
            transaction.Rollback();
        }
        catch (Exception ex2)
        {
            // This catch block will handle any errors that may have occurred
            // on the server that would cause the rollback to fail, such as
            // a closed connection.
            Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
            Console.WriteLine("  Message: {0}", ex2.Message);
        }
    }
}