[C#] SQLServer 시간 초과 예외를 포착하는 방법

다르게 처리 할 수 ​​있도록 특별히 SQL 서버 시간 초과 예외를 포착해야합니다. SqlException을 잡은 다음 메시지 문자열에 “Timeout”이 포함되어 있는지 확인할 수 있지만 더 나은 방법이 있는지 궁금합니다.

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

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



답변

시간 초과를 확인하려면 ex.Number의 값을 확인하십시오. -2이면 시간 초과 상황입니다.

-2는 SQL Server 용 MDAC 드라이버 인 DBNETLIB에서 반환 된 시간 초과 오류 코드입니다. 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");
    }
}


답변

여기 : 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 오류 코드)

“일반 네트워크 오류”도 시간 초과 예외로 처리합니다. 업데이트 / 삽입 / 삭제 쿼리가 장기 실행 트리거를 발생시키는 경우와 같은 드문 경우에만 발생합니다.


답변

C # 6 용으로 업데이트되었습니다.

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

매우 간단하고보기 좋습니다 !!


답변

SqlException.ErrorCode 속성의 값은 무엇입니까? 그것으로 작업 할 수 있습니까?

시간 초과가 발생하면 -2146232060에 대한 코드를 확인하는 것이 좋습니다 .

나는 이것을 당신의 데이터 코드에서 정적 const로 설정할 것입니다.


답변

확실하지 않지만 실행 시간이 초과되거나 명령 시간이 초과 된 경우 클라이언트는 SQL Server에 “ABORT”를 보낸 다음 쿼리 처리를 중단합니다. 트랜잭션이 롤백되지 않고 잠금이 해제되지 않습니다. 이 문제를 해결하려면 저장 프로 시저에서 트랜잭션을 제거하고 .Net 코드에서 SQL 트랜잭션을 사용하여 sqlException을 관리합니다.


답변

클라이언트가 ABORT를 보낼 때 트랜잭션이 롤백되지 않습니다. 이 동작을 방지하려면 https://docs.microsoft.com/en-us/sql/t-sql/statements/set-xact-abort-transact-sql?view=sql-server-ver15에서 SET_XACT_ABORT를 사용해야합니다.


답변