다음을 통해 공유


MSSQLSERVER_3617

적용 대상: SQL Server

세부 정보

attribute
제품 이름 SQL Server
이벤트 ID 3617
이벤트 원본 MSSQLSERVER
구성 요소 SQLEngine
심볼 이름 SYS_ATTN
메시지 텍스트

설명

실행 중간에 있는 쿼리가 애플리케이션 또는 사용자에 의해 취소되거나 연결이 끊어지면 오류 3617이 발생합니다. 애플리케이션에서 이 쿼리를 취소하면 데이터베이스 엔진 주의 이벤트가 발생합니다. 주의 이벤트는 쿼리 실행을 종료하라는 클라이언트 애플리케이션의 요청을 등록하는 SQL Server 이벤트입니다. 확장 이벤트 또는 SQL 추적 주의 이벤트 클래스를 사용하여 SQL Server 쪽에서 주의 이벤트를 추적할 수 있습니다. 주의는 내부적으로 오류 3617로 표시됩니다.

주의(쿼리 취소)는 SQL Server에서 처리하는 가장 일반적인 TDS 이벤트 중 하나입니다. 쿼리 취소 요청이 도착하면 세션/요청에 대한 주의 비트가 설정됩니다. 세션에서 양보점(yield point)을 처리할 때 주의가 선택 및 적용됩니다. 주의 및 다른 구성 요소와 상호 작용하는 방법에 대한 자세한 내용은 작업, 작업자, 스레드, 스케줄러, 세션, 연결, 요청을 참조 하세요. 이 모든 것이 무엇을 의미하나요?

사용자 작업

원인 요약:

  • 쿼리가 예상 기간(구성된 쿼리 시간 제한 값보다 작음) 이내에 완료되도록 함
  • 쿼리 또는 명령 시간 제한 늘리기
  • 사용자가 쿼리 실행을 수동으로 취소했는지 확인
  • 애플리케이션 또는 OS가 예기치 않게 종료되었는지 확인

쿼리가 예상 기간(구성된 쿼리 시간 제한 값보다 작음) 내에 완료되도록 합니다. 주의 이벤트의 가장 일반적인 이유는 쿼리 시간 제한 값을 초과하여 애플리케이션에서 쿼리가 자동으로 종료되기 때문입니다. 쿼리/명령 제한 시간 값이 30초로 설정되고 쿼리가 단일 데이터 패킷도 클라이언트 애플리케이션으로 반환하지 않는 경우 후자는 쿼리를 취소합니다. 이러한 경우 가장 좋은 방법은 쿼리가 너무 오래 걸리는 이유를 이해하고 기간을 줄이기 위해 적절한 단계를 수행하는 것입니다.

쿼리 또는 명령 시간 제한 늘리기: 취소된 쿼리가 미리 설정된 기준 기간 내에 실행 중이지만 명령 시간 제한에 도달한 경우 데이터베이스 애플리케이션에서 시간 제한 값을 늘리는 것이 좋습니다.

사용자가 쿼리 실행을 수동으로 취소했는지 확인합니다. 경우에 따라 사용자가 쿼리를 취소했기 때문에 주의 이벤트가 발생할 수 있습니다. 이러한 경우 사용자의 기대치가 쿼리의 실제 속도를 초과하는지 확인하고 쿼리를 튜닝하거나 예상 기준을 문서화하여 이를 해결하는 것이 신중할 수 있습니다.

애플리케이션 또는 OS가 쿼리 또는 연결을 예기치 않게 종료했는지 또는 애플리케이션 자체가 종료되었는지 확인합니다. 상황을 조사하여 애플리케이션 끝에서 발생하는 상황을 파악합니다. 애플리케이션 로그 또는 시스템 로그를 검사하면 가능한 근본 원인에 대한 단서를 제공할 수 있습니다.

주의 및 트랜잭션

일반적으로 주의 이벤트는 애플리케이션이 쿼리 시간 제한에 도달하고 쿼리를 취소할 때 발생합니다. 주의 이벤트가 발생하면 SQL Server는 열려 있는 트랜잭션을 자동으로 롤백하지 않습니다. 트랜잭션을 롤백하는 것은 애플리케이션의 책임이며 다음과 같은 몇 가지 일반적인 처리 방법이 있습니다.

  • SQL Server에 연결할 때 SET XACT_ABORT ON을 사용하도록 설정하여 트랜잭션 롤백을 제어합니다. 애플리케이션에서 이 작업을 수행하지 않으면 분리된 트랜잭션이 발생합니다.

  • 더 일반적으로 애플리케이션은 .를 사용하여 try.. catch... finally오류를 처리합니다. try 블록에서 트랜잭션을 열고 오류가 발생하면 catch에서 트랜잭션을 롤백하거나 마지막으로 차단합니다.

예를 들어 다음과 같습니다.


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