SQL Database 및 SQL Managed Instance에서 일시적인 연결 오류 문제 해결

적용 대상:Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics

이 문서에서는 클라이언트 애플리케이션이 Azure SQL Database, Azure SQL Managed Instance 및 Azure Synapse Analytics와 상호 작용할 때 발생하는 연결 오류 및 일시적 오류를 방지, 해결, 진단, 완화하는 방법에 대해 설명합니다. 재시도 논리를 구성하고 연결 문자열을 빌드하며 타 연결 설정을 조정하는 방법에 대해 알아봅니다.

일시적인 오류(일시 장애)

일시 결함으로도 알려진 일시적인 오류에는 자체적으로 신속히 확인되는 원인이 있습니다. 일시적 오류가 발생하는 이유는 가끔 Azure 시스템에서 다양한 워크로드의 부하를 더 효율적으로 분산하기 위해 하드웨어를 신속하게 변경하는 경우가 포함됩니다. 이러한 재구성 이벤트는 60초 이내에 완료됩니다. 이 재구성 기간 중에는 SQL Database의 데이터베이스에 대한 연결에 문제가 있을 수 있습니다. 데이터베이스에 연결하는 애플리케이션은 이러한 일시적인 오류를 예상하도록 빌드되어야 합니다. 이를 처리하기 위해 사용자에게 애플리케이션 오류로 표시되는 대신 해당 코드에서 재시도 논리를 구현합니다.

클라이언트 프로그램에서 ADO.NET을 사용하는 경우 사용자 프로그램에 SqlException이 throw되어 일시적 오류가 발생했다는 메시지가 표시됩니다.

연결 및 명령

다음에 따라 SQL Database 및 SQL Managed Instance 연결을 다시 시도하거나 다시 설정합니다.

  • 연결 시도 중 일시적 오류가 발생할 경우

몇 초 지연한 후에 연결을 다시 시도합니다.

  • SQL Database 및 SQL Managed Instance 쿼리 명령을 실행하는 동안 일시적인 오류가 발생함

명령을 즉시 다시 시도하지 않습니다. 대신, 지연 후에 연결을 새로 고쳐야 합니다. 그런 후 명령을 다시 시도합니다.

일시적인 오류에 대한 재시도 논리

간혹 일시적 오류가 발생하는 클라이언트 프로그램에 재시도 논리가 포함된 경우 더욱 견고해질 수 있습니다. 프로그램이 타사 미들웨어를 통해 SQL Database의 데이터베이스와 통신하는 경우 공급업체에 문의하여 미들웨어에 일시적 오류에 대한 재시도 논리가 포함되어 있는지 여부를 확인해야 합니다.

재시도 원칙

  • 오류가 일시적인 경우 연결 열기를 다시 시도합니다.
  • 일시적인 오류로 인해 실패한 SQL Database 또는 SQL Managed Instance SELECT 문은 직접 다시 시도하지 마세요. 대신, 새로 연결한 다음 SELECT를 다시 시도합니다.
  • 일시적 오류로 인해 SQL Database 또는 SQL Managed Instance UPDATE 문이 실패할 경우 UPDATE를 다시 시도하기 전에 새 연결을 설정합니다. 재시도 논리는 전체 데이터베이스 트랜잭션이 완료되었는지 또는 전체 트랜잭션이 롤백되었는지 여부를 확인해야 합니다.

재시도에 대한 기타 고려 사항

  • 업무 시간 후 자동으로 시작되어 아침 전까지 완료되는 배치 프로그램은 재시도 간격을 길게 설정할 수 있습니다.
  • 사용자 인터페이스 프로그램은 기다리는 시간이 길 때 사용자가 포기하는 경향이 있는지를 고려해야 합니다. 몇 초마다 재시도하는 정책을 사용할 경우 시스템의 요청 수가 너무 많아지므로 사용하지 않아야 합니다.

재시도 간격 증가

첫 번째 재시도 전에 5초간 대기하는 것이 좋습니다. 5초보다 짧은 지연 후 재시도는 클라우드 서비스에 많은 위험이 있습니다. 각 후속 재시도에 대해 지연 시간은 최대 60초까지 기하급수적으로 증가해야 합니다.

ADO.NET을 사용하는 클라이언트에 대한 차단 기간의 설명은 연결 풀링(ADO.NET)을 참조하세요.

또한 프로그램이 자체적으로 종료하기 전까지 최대 재시도 횟수를 설정할 수 있습니다.

재시도 논리가 포함된 코드 샘플

재시도 논리가 포함된 코드 예제는 다음에 있습니다.

재시도 논리 테스트

재시도 논리를 테스트하려면 프로그램이 실행 중인 동안 수정할 수 있는 오류를 일으키거나 시뮬레이션해야 합니다.

네트워크에서 연결을 끊고 테스트

재시도 논리를 테스트할 수 있는 한 가지 방법은 프로그램이 실행되는 동안 네트워크에서 클라이언트 컴퓨터 연결을 끊는 것입니다. 오류는 다음과 같습니다.

  • SqlException.Number = 11001
  • 메시지: "해당 호스트가 없습니다"

첫 번째 다시 시도의 일부로 클라이언트 컴퓨터를 네트워크에 다시 연결한 다음, 연결을 시도할 수 있습니다.

이 테스트를 실제로 사용하려면 프로그램을 시작하기 전에 네트워크와 컴퓨터 간 케이블을 분리합니다. 그러면 프로그램에서 프로그램이 다음과 같이 작동하는 런타임 매개 변수를 인식합니다.

  • 오류 목록에 일시적 오류로 간주하기 위해 11001을 일시적으로 추가합니다.
  • 평상 시와 같이 첫 번째 연결을 시도합니다.
  • 오류가 확인되면 목록에서 11001을 제거합니다.
  • 사용자에게 컴퓨터를 네트워크에 연결하라는 메시지를 표시합니다.
  • Console.ReadLine 메서드 또는 확인 단추가 포함된 대화 상자를 사용하여 추가 실행을 일시 정지합니다. 사용자가 컴퓨터와 네트워크 간 케이블을 연결한 다음 Enter 키를 누릅니다.
  • 다시 연결을 시도합니다. 정상적으로 연결되어야 합니다.

연결할 때 사용자 이름의 철자를 검사합니다.

프로그램이 첫 번째 연결 시도 전에 의도적으로 사용자 이름의 철자를 잘못 입력할 수 있습니다. 오류는 다음과 같습니다.

  • SqlException.Number = 18456
  • 메시지: "사용자 'WRONG_MyUserName'에 대한 로그인에 실패했습니다."

프로그램은 첫 번째 재시도 중 오타를 수정한 다음 연결을 시도할 수 있습니다.

이 테스트를 실제로 사용하기 위해 프로그램에서 프로그램이 다음과 같이 작동하는 런타임 매개 변수를 인식합니다.

  • 오류 목록에 일시적 오류로 간주하기 위해 18456을 일시적으로 추가합니다.
  • 사용자 이름에 의도적으로 'WRONG_'을 추가합니다.
  • 오류가 확인되면 목록에서 18456을 제거합니다.
  • 사용자 이름에서 'WRONG_'을 제거합니다.
  • 다시 연결을 시도합니다. 정상적으로 연결되어야 합니다.

연결 다시 시도에 대한 .NET SqlConnection 매개 변수

클라이언트 프로그램이 .NET Framework 클래스 System.Data.SqlClient.SqlConnection을 사용하여 Azure SQL Database의 데이터베이스에 연결하는 경우 .NET 4.6.1 이상 버전(또는 .NET Core)을 사용하므로 해당 연결 다시 시도 기능을 사용할 수 있습니다. 이 기능에 대한 자세한 내용은 SqlConnection.ConnectionString 속성을 참조하세요.

SqlConnection 개체에 대한 연결 문자열을 작성하는 경우 다음 매개 변수 중에서 값을 조정합니다.

  • ConnectRetryCount: 기본값은 1입니다. 범위는 0에서 255까지 입니다.
  • ConnectRetryInterval: 기본값은 10초입니다. 범위는 1에서 60까지 입니다.
  • 연결 제한 시간:기본값은 15초입니다. 범위는 0에서 2147483647까지 입니다.
  • 명령 시간 제한: 기본값은 30초입니다. 범위는 0에서 2147483647까지 입니다.

연결 다시 시도 설정(ConnectRetryCountConnectRetryInterval)은 연결 복원력에 적용됩니다. 연결 복원력에는 다음과 같은 고유 형식이 포함됩니다.

  • 연결 복원력 열기는 초기 SqlConnection.Open 또는 OpenAsync() 메서드를 나타냅니다. 첫 번째 연결 시도는 0으로 계산됩니다. ConnectRetryCount는 후속 재시도에 적용됩니다. 따라서 연결 0이 실패하면(즉시 발생하지 않을 수 있음) ConnectRetryInterval이 먼저 적용되고 후속 ConnectRetryCount(및 ConnectRetryInterval) 시도가 수행됩니다. 모든 재시도를 활용하려면 연결 시간 제한 속성이 모든 시도에 대한 시간을 제공해야 합니다.

  • 유휴 연결 복원력은 끊어진 기존 유휴 연결의 자동 검색 및 다시 연결을 나타냅니다. 끊어진 유휴 연결을 다시 연결하려는 첫 번째 시도는 첫 번째 다시 시도로 계산됩니다. 모든 재시도를 활용하려면 명령 시간 제한이 모든 시도에 대한 시간을 제공해야 합니다.

예: ConnectRetryCountConnectRetryInterval 매개 변수에 대해 다음 값을 가정합니다.

ConnectRetryCount: 3 ConnectRetryInterval: 10초

다음 시나리오에서 이러한 값이 어떻게 사용되는지 확인합니다.

시나리오: 새 연결

4:10:00 - Connection.Open() - 0 시도

4:10:01 - 연결 오류가 감지됨

4:10:11 - 다시 시도 1 -->ConnectRetryInterval 이후 첫 번째 다시 시도 발생

4:10:21 - 다시 시도 2

4:10:31 - 다시 시도 3

이 시나리오에서는 선택한 값이 다음 조건을 충족해야 합니다.
Connection Timeout > = ConnectRetryCount * ConnectionRetryInterval

예를 들어 개수가 3이고 간격이 10초인 경우 시간 제한이 29초이면 시스템의 세 번째이자 마지막 연결 재시도에 충분한 시간을 제공하지 않게 됩니다.

29 < 3 * 10

시나리오: 유휴 연결

ConnectRetryCount: 3 ConnectRetryInterval: 10초

4:10:00 - 명령 실행 시 끊어진 연결 감지

4:10:00 - 다시 시도 1 -->첫 번째 다시 시도가 즉시 발생

4:10:10 - 다시 시도 2

4:10:20 - 다시 시도 3

이는 초기 연결이 아닙니다. 따라서 연결 시간 제한은 적용되지 않습니다. 그러나 명령 실행 중에 연결 복구가 발생하기 때문에 명령 시간 제한 설정이 적용됩니다. 명령 시간 제한 기본값은 30초입니다. 일반적인 상황에서는 연결 복구가 빠르지만 일시적인 중단으로 인해 복구에 명령 실행 시간이 걸릴 수 있습니다.

이 시나리오에서 유휴 연결 복구 재시도를 최대한 활용하려면 선택한 값이 다음 조건을 충족해야 합니다.
Command Timeout > (ConnectRetryCount - 1) * ConnectionRetryInterval

예를 들어 개수가 3이고 간격이 10초인 경우 20초 미만의 명령 시간 제한 값은 세 번째 및 최종 재시도에 충분한 시간을 주지 않습니다. (3 - 1) * 10 = 20`

또한 명령 자체는 연결이 복구된 후 실행하는 데 시간이 필요하다는 점을 고려합니다.

참고

이러한 시나리오에서 제공되는 기간 값은 데모 전용입니다. 두 시나리오의 실제 검색 시간은 기본 인프라에 따라 달라집니다.

연결 및 명령

ConnectRetryCountConnectRetryInterval 매개 변수를 사용하면 SqlConnection 개체는 프로그램에 제어를 반환하는 등 프로그램에 전달하거나 신경 쓰지 않고 연결 작업을 다시 시도합니다. 다시 시도는 다음과 같은 상황에서 발생할 수 있습니다.

  • SqlConnection.Open 메서드 호출
  • SqlConnection.Execute 메서드 호출

미묘한 문제가 있습니다. 임시 오류가 발생할 경우 쿼리 가 실행되는 동안 SqlConnection 개체는 연결 작업을 다시 시도하지 않습니다. 확실히 쿼리를 다시 시도하지 않습니다. 그러나 SqlConnection 는 매우 신속하게 실행에 쿼리를 보내기 전에 연결을 검사합니다. 빠른 검사가 연결 문제를 감지하면 SqlConnection 은 연결 작업을 다시 시도합니다. 다시 시도가 성공하면 쿼리는 실행을 위해 전송됩니다.

ConnectRetryCount가 애플리케이션 다시 시도 논리에 결합되어야 하는지 여부

애플리케이션에는 강력한 사용자 지정 다시 시도 논리가 있다고 가정합니다. 연결 작업을 4번 다시 시도할 수 있습니다. ConnectRetryIntervalConnectRetryCount =3을 연결 문자열에 추가하는 경우 다시 시도 횟수가 4 * 3 = 12로 늘어납니다. 이러한 많은 수의 다시 시도를 할 의도가 아닐 수 있습니다.

SQL Database의 데이터베이스에 연결

연결: 연결 문자열

데이터베이스에 연결하는 데 필요한 연결 문자열은 SQL Server에 연결하는 데 사용되는 문자열과 약간 다릅니다. Azure Portal에서 데이터베이스에 대한 연결 문자열을 복사할 수 있습니다.

Azure 포털에서 연결 문자열 가져오기

Azure Portal에서 클라이언트 프로그램이 Azure SQL Database와 상호 작용하는 데 필요한 연결 문자열을 가져올 수 있습니다.

  1. 모든 서비스>SQL 데이터베이스를 클릭합니다.

  2. SQL Database 창 왼쪽 위에 있는 필터 텍스트 상자에 데이터베이스 이름을 입력합니다.

  3. 해당 데이터베이스에 대한 행을 선택합니다.

  4. 데이터베이스에 대한 창이 표시된 후 시각적 편의를 위해 최소화 버튼을 선택하여 찾아보기 및 데이터베이스 필터링에 사용한 블레이드를 축소합니다.

  5. 데이터베이스 창에서 데이터베이스 연결 문자열 표시를 선택합니다.

  6. 적절한 연결 문자열을 복사합니다. 즉, ADO.NET 연결 라이브러리를 사용하려는 경우, ADO.NET 탭에서 적절한 문자열을 복사합니다.

    Copy the ADO connection string for your database

  7. 필요에 따라 연결 문자열을 편집합니다. 즉, 사용자 이름 또는 서버 이름이 너무 긴 경우, 사용자 이름에서 “@<servername>”을 제거하거나 연결 문자열에 암호를 삽입합니다.

  8. 한 가지 형식이나 다른 형식으로 연결 문자열 정보를 클라이언트 프로그램 코드에 붙여넣습니다.

자세한 내용은 연결 문자열 및 구성 파일을 참조하세요.

연결: IP 주소

SQL Database가 사용자의 클라이언트 프로그램을 호스트하는 컴퓨터의 IP 주소의 통신을 수락하도록 구성해야 합니다. 이 구성을 설정하려면 Azure Portal을 통해 방화벽 설정을 편집합니다.

IP 주소를 구성하지 않을 경우 프로그램이 실패하고 간단한 오류 메시지로 필요한 IP 주소를 표시합니다.

  1. Azure Portal에 로그인합니다.

  2. 왼쪽에 있는 목록에서 모든 서비스를 선택합니다.

  3. 스크롤하여 SQL 서버를 선택합니다.

    Find your Azure SQL Database server in the portal

  4. 필터 텍스트 상자에 서버 이름을 입력하기 시작합니다. 해당 행이 표시됩니다.

  5. 서버에 대한 행을 선택합니다. 서버 창이 표시됩니다.

  6. 서버 창에서 설정을 선택합니다.

  7. 방화벽을 선택합니다.

    Select Settings > Firewall

  8. 클라이언트 IP 추가를 선택합니다. 첫 번째 텍스트 상자에 새 규칙의 이름을 입력합니다.

  9. 사용하도록 설정하려는 범위의 하한 및 상한 IP 주소 값을 입력합니다.

    • 하한 값은 .0으로 끝나고 상한 값은 .255로 끝나도록 하면 편리할 수 있습니다.
  10. 저장을 선택합니다.

자세한 내용은 SQL Database에 방화벽 설정 구성을 참조하세요.

연결: 포트

일반적으로 클라이언트 프로그램을 호스팅하는 컴퓨터에서 포트 1433이 아웃바운드 통신에 개방되어 있는지 여부만 확인해야 합니다.

예를 들어 클라이언트 프로그램이 Windows 컴퓨터에 호스팅된 경우 호스트의 Windows 방화벽을 사용하여 포트 1433을 열 수 있습니다.

  1. 제어판을 엽니다.
  2. 모든 제어판 항목>Windows 방화벽>고급 설정>아웃바운드 규칙>동작>새 규칙을 선택합니다.

클라이언트 프로그램이 Azure VM(가상 머신)에서 호스팅되는 경우 ADO.NET 4.5 및 SQL Database에 대한 1433 이외의 포트를 참조하세요.

데이터베이스의 포트 및 IP 주소 구성에 대한 배경 정보는 Azure SQL Database 방화벽을 참조하세요.

연결: ADO.NET 4.6.2 이상

프로그램에서 System.Data.SqlClient.SqlConnection과 같은 ADO.NET 클래스를 사용하여 SQL Database에 연결하는 경우 .NET Framework 버전 4.6.2 이상을 사용하는 것이 좋습니다.

ADO.NET 4.6.2를 사용하여 시작

  • Azure SQL에 대한 연결 열기 시도가 즉시 다시 시도되므로 클라우드 기반 애플리케이션의 성능이 향상됩니다.

ADO.NET 4.6.1을 사용하여 시작

  • SQL Database의 경우 SqlConnection.Open 메서드를 사용하여 연결을 열 때 안정성이 향상됩니다. Open 메서드는 이제 연결 제한 시간 내에 특정 오류에 대해 일시적인 오류에 대한 응답으로 최적의 재시도 메커니즘을 통합합니다.
  • 연결 풀링이 제공됩니다. 이는 프로그램에 제공하는 연결 개체가 올바르게 작동하는지를 효율적으로 확인합니다.

연결 풀에서 연결 개체를 사용하는 경우 프로그램을 바로 사용하지 않으면 해당 프로그램에서 연결을 일시적으로 닫는 것이 좋습니다. 연결을 다시 여는 데 비용이 많이 들지 않지만 새 연결을 만드는 데 비용이 많이 듭니다.

ADO.NET 4.0 이전 버전을 사용할 경우 최신 ADO.NET으로 업그레이드하는 것이 좋습니다. 2018년 8월 현재 ADO.NET 4.6.2를 다운로드할 수 있습니다.

진단

진단: 유틸리티에서 연결할 수 있는지 여부 테스트

프로그램에서 SQL Database의 데이터베이스에 연결할 수 없을 경우 한 가지 진단 방법으로 유틸리티 프로그램에 연결해 볼 수 있습니다. 유틸리티는 프로그램에서 사용하는 것과 동일한 라이브러리를 사용하여 연결하는 것이 가장 좋습니다.

모든 Windows 컴퓨터에서 이러한 유틸리티를 시도할 수 있습니다.

  • ADO.NET을 사용하여 연결하는 SQL Server Management Studio(ssms.exe)
  • ODBC를 사용하여 연결하는 sqlcmd.exe

프로그램이 연결된 후에는 짧은 SQL SELECT 쿼리가 작동하는지 테스트합니다.

진단: 개방 포트 점검

포트 문제로 인해 연결 시도 실패가 의심되는 경우 컴퓨터에서 포트 구성에 대해 보고하는 유틸리티를 실행할 수 있습니다.

Linux에서 다음 유틸리티는 도움이 될 수 있습니다.

  • netstat -nap
  • nmap -sS -O 127.0.0.1: 사용자의 IP 주소가 되도록 예제 값을 변경합니다.

Windows에서는 PortQry.exe 유틸리티가 도움이 됩니다. 다음은 SQL Database의 데이터베이스에서 포트 상황에 대해 쿼리하기 위해 노트북 컴퓨터에서 실행한 실행 프로그램 예제입니다.

[C:\Users\johndoe\]
>> portqry.exe -n johndoesvr9.database.windows.net -p tcp -e 1433

Querying target system called: johndoesvr9.database.windows.net

Attempting to resolve name to IP address...
Name resolved to 23.100.117.95

querying...
TCP port 1433 (ms-sql-s service): LISTENING

[C:\Users\johndoe\]
>>

진단: 오류 기록

간헐적 문제는 며칠 또는 몇 주간 일반 패턴을 발견하여 진단하는 것이 가장 좋은 경우가 있습니다.

클라이언트에서 발생한 모든 오류를 기록하면 진단에 도움이 될 수 있습니다. 로그 항목과 SQL Database에서 내부적으로 기록하는 오류 데이터의 상관 관계를 분석할 수 있습니다.

Enterprise Library 6(EntLib60)은 로깅을 지원하기 위해 .NET 관리 클래스를 제공합니다. 자세한 내용은 5 - 간단한 애플리케이션 블록 로깅 사용을 참조하세요.

진단: 시스템 로그에서 오류 확인

다음은 오류 로그 및 기타 정보를 쿼리하는 몇 가지 Transact-SQL SELECT 문입니다.

로그 쿼리 설명
SELECT e.*
FROM sys.event_log AS e
WHERE e.database_name = 'myDbName'
AND e.event_category = 'connectivity'
AND 2 >= DateDiff
  (hour, e.end_time, GetUtcDate())
ORDER BY e.event_category,
  e.event_type, e.end_time;
sys.event_log 보기는 일시적인 오류 또는 연결 실패를 일으킬 수 있는 일부를 포함하여 개별 이벤트에 대한 정보를 제공합니다.

이상적으로 start_time 또는 end_time 값을 클라이언트 프로그램에 문제가 발생하는 방법에 대한 정보와 함께 상호 연결할 수 있습니다.

마스터 데이터베이스에 연결하여 이 쿼리를 실행해야 합니다.
SELECT c.*
FROM sys.database_connection_stats AS c
WHERE c.database_name = 'myDbName'
AND 24 >= DateDiff
  (hour, c.end_time, GetUtcDate())
ORDER BY c.end_time;
sys.database_connection_stats 보기는 추가 진단을 위해 이벤트 유형별로 집계된 개수를 제공합니다.

마스터 데이터베이스에 연결하여 이 쿼리를 실행해야 합니다.

진단: SQL Database 로그에서 문제 이벤트 검색

SQL Database 로그에서 문제 이벤트에 대한 항목을 검색할 수 있습니다. 마스터 데이터베이스에서 다음 Transact-SQL SELECT 문을 시도해 보세요.

SELECT
   object_name
  ,CAST(f.event_data as XML).value
      ('(/event/@timestamp)[1]', 'datetime2')                      AS [timestamp]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="error"]/value)[1]', 'int')             AS [error]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="state"]/value)[1]', 'int')             AS [state]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="is_success"]/value)[1]', 'bit')        AS [is_success]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="database_name"]/value)[1]', 'sysname') AS [database_name]
FROM
  sys.fn_xe_telemetry_blob_target_read_file('el', null, null, null) AS f
WHERE
  object_name != 'login_event'  -- Login events are numerous.
  and
  '2015-06-21' < CAST(f.event_data as XML).value
        ('(/event/@timestamp)[1]', 'datetime2')
ORDER BY
  [timestamp] DESC
;

sys.fn_xe_telemetry_blob_target_read_file에서 반환된 몇 개 행

다음 예제에서는 반환된 행의 모양을 보여 줍니다. 여기에 표시된 null 값은 다른 행에서 null이 아닌 경우가 많습니다.

object_name                   timestamp                    error  state  is_success  database_name

database_xml_deadlock_report  2015-10-16 20:28:01.0090000  NULL   NULL   NULL        AdventureWorks

Enterprise Library 6

Enterprise Library 6(EntLib60)은 SQL Database를 포함한 견고한 클라우드 서비스 클라이언트를 구현할 수 있는 .NET 클래스의 프레임워크입니다. EntLib60을 이용할 수 있는 각 영역에 해당하는 항목을 찾으려면 Enterprise Library 6 – 2013년 4월을 참조하세요.

일시적 오류 처리에 대한 재시도 논리는 EntLib60을 이용할 수 있는 한 가지 영역입니다. 자세한 내용은 4 - 모든 성공의 인내와 비밀: 일시적 오류 처리 애플리케이션 블록 사용을 참조하세요.

참고

EntLib60에 대한 소스 코드는 다운로드 센터의 공용 다운로드에서 사용할 수 있습니다. Microsoft는 EntLib에 추가 기능 또는 유지 관리를 업데이트할 계획이 없습니다.

일시적 오류 및 재시도용 EntLib60 클래스

다음 EntLib60 클래스는 특히 재시도 논리에 유용합니다. 이러한 클래스는 모두 Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling 네임스페이스에 있으며, 여기에서 찾을 수 있습니다.

Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling 네임스페이스:

  • RetryPolicy 클래스
    • ExecuteAction 메서드
  • ExponentialBackoff 클래스
  • SqlDatabaseTransientErrorDetectionStrategy 클래스
  • ReliableSqlConnection 클래스
    • ExecuteCommand 메서드

Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.TestSupport네임스페이스의

  • AlwaysTransientErrorDetectionStrategy 클래스
  • NeverTransientErrorDetectionStrategy 클래스

다음은 EntLib60에 대한 정보의 일부 링크입니다.

EntLib60: 로깅 블록

  • 로깅 블록은 다음 작업을 할 수 있는 매우 유연하고 구성 가능한 솔루션입니다.
    • 다양한 위치에서 메시지를 만들고 저장합니다.
    • 메시지를 분류 및 필터링합니다.
    • 디버깅, 추적, 감사 및 일반 로깅 요구 사항에 유용한 문맥 정보를 수집합니다.
  • 로깅 블록은 대상 로깅 저장소의 위치 및 유형과 상관없이 애플리케이션 코드의 일관성을 유지하도록 로그 대상에서 로깅 기능을 추상화합니다.

자세한 내용은 5 - 간단한 애플리케이션 블록 로깅 사용을 참조하세요.

EntLib60 IsTransient 메서드 소스 코드

다음으로, SqlDatabaseTransientErrorDetectionStrategy 클래스에는 IsTransient 메서드에 대한 C# 소스 코드가 있습니다. 소스 코드는 2013년 4월처럼 일시적 오류로 간주할 오류와 재시도할 만한 오류를 명확히 구분합니다.

public bool IsTransient(Exception ex)
{
  if (ex != null)
  {
    SqlException sqlException;
    if ((sqlException = ex as SqlException) != null)
    {
      // Enumerate through all errors found in the exception.
      foreach (SqlError err in sqlException.Errors)
      {
        switch (err.Number)
        {
            // SQL Error Code: 40501
            // The service is currently busy. Retry the request after 10 seconds.
            // Code: (reason code to be decoded).
          case ThrottlingCondition.ThrottlingErrorNumber:
            // Decode the reason code from the error message to
            // determine the grounds for throttling.
            var condition = ThrottlingCondition.FromError(err);

            // Attach the decoded values as additional attributes to
            // the original SQL exception.
            sqlException.Data[condition.ThrottlingMode.GetType().Name] =
              condition.ThrottlingMode.ToString();
            sqlException.Data[condition.GetType().Name] = condition;

            return true;

          case 10928:
          case 10929:
          case 10053:
          case 10054:
          case 10060:
          case 40197:
          case 40540:
          case 40613:
          case 40143:
          case 233:
          case 64:
            // DBNETLIB Error Code: 20
            // The instance of SQL Server you attempted to connect to
            // does not support encryption.
          case (int)ProcessNetLibErrorCode.EncryptionNotSupported:
            return true;
        }
      }
    }
    else if (ex is TimeoutException)
    {
      return true;
    }
    else
    {
      EntityException entityException;
      if ((entityException = ex as EntityException) != null)
      {
        return this.IsTransient(entityException.InnerException);
      }
    }
  }

  return false;
}

다음 단계