c# - 데이터베이스 연결 문제를 해결하는 올바른 방법




sql-server ado.net (5)

데이터베이스에 연결하려고 할 때 오류가 발생했습니다.

SQL Server에 연결하는 동안 네트워크 관련 또는 인스턴스 관련 오류가 발생했습니다. 서버를 찾을 수 없거나 액세스 할 수 없습니다. 인스턴스 이름이 올 바르고 SQL Server가 원격 연결을 허용하도록 구성되어 있는지 확인하십시오. (공급자 : 명명 된 파이프 공급자, 오류 : 40 - SQL Server에 대한 연결을 열 수 없음)

지금 때로는이 오류가 발생하고 때로는 예를 들어 그다지하지 않습니다. 처음 프로그램을 실행하면 연결이 성공적으로 열리고 두 번째 시간에 실행될 때이 오류가 발생하고 프로그램을 다시 실행할 때 다음 순간이 발생합니다. 그때 나는 오류가 발생하지 않습니다.

SSMS를 통해 동일한 데이터베이스 서버에 연결하려고하면 성공적으로 연결할 수 있지만 내 네트워크에서만이 네트워크 문제가 발생합니다.

데이터베이스가 AZURE의로컬에 없습니다.

내 로컬 데이터베이스에서이 오류가 발생하지 않습니다.

코드 :

public class AddOperation
{
    public void Start()
    {
          using (var processor = new MyProcessor())
          {
              for (int i = 0; i < 2; i++)
              {
                  if(i==0)
                  {
                     var connection = new SqlConnection("Connection string 1");
                     processor.Process(connection);
                  }
                  else
                  {
                      var connection = new SqlConnection("Connection string 2");
                      processor.Process(connection);
                  }   
              }
          }
    }       
}

public class MyProcessor : IDisposable
{
    public void Process(DbConnection cn)
        {
            using (var cmd = cn.CreateCommand())
            {
                cmd.CommandText = "query";
                cmd.CommandTimeout = 1800;
                cn.Open();//Sometimes work sometimes dont
                using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                { 
                   //code
                }
            }
        }
}

그래서 나는 2 가지와 혼동한다.

1) ConnectionTimeout : 내가 connectiontimeout을 늘려야하는지 여부 및 내 비정상적인 연결 문제를 해결할 것인가?

2) 재시도 시도 정책 : 다음 과 같이 재시도 연결 메커니즘을 구현해야합니까?

public static void OpenConnection(DbConnection cn, int maxAttempts = 1)
        {
            int attempts = 0;
            while (true)
            {
                try
                {
                    cn.Open();
                    return;
                }
                catch
                {
                    attempts++;
                    if (attempts >= maxAttempts) throw;
                }
            }
        }

나는 위의 2 옵션과 혼동 스럽다.

아무도 나에게이 문제를 다루는 더 좋은 방법이 무엇인지 제안 해 줄 수 있습니까?


SQL Express 또는 Workgroup Edition을 사용하고 있습니까? 그렇다면 서버가 너무 바빠서 응답 할 수 없습니다.

네트워크 문제를 배제하려면 명령 프롬프트에서 PING -t SqlServername . 모든 핑이 돌아 왔습니까? 아니면 일부 손실 되었습니까? 이는 장애가 발생한 스위치처럼이 오류를 유발할 수도있는 네트워크 중단의 표시 일 수 있습니다. 모든 것이 손실 된 경우 (데이터베이스 연결이 작동하는 경우) 핑이 어딘가의 방화벽에 의해 차단 될 가능성이 있습니다. 해당 블록을 찾아 일시적으로 차단 해제하면 진단에 도움이 될 수 있습니다.

오류 메시지는 명명 된 파이프를 사용하고 있음을 나타냅니다. 목적에 따라 명명 된 파이프를 사용하고 있습니까? 대부분의 시나리오 (Azure 데이터베이스 포함)에서는 SQL Server 구성 관리자에서 TCP / IP를 사용하도록 설정하고 명명 된 파이프를 사용하지 않도록 설정하는 것이 좋습니다.

Azure 데이터베이스가 '멀리 떨어져있는'방식에 따라 라우터 및 방화벽으로 인해 지연이 발생하여 Kerberos 및 / 또는 관련 타이밍이 흐려질 수 있습니다. 인스턴스를 열거하기 위해 포트 1434 로의 왕복을 피하기 위해 연결 문자열의 포트를 사용하여이를 극복 할 수 있습니다. 이미 FQDN을 사용하고 있다고 가정합니다. 예 : server \ instance, port


SQL 서버에 연결하는 데 걸리는 시간은 여러 단계가 있기 때문에 제한 시간을 늘려야합니다. 따라서 연결을 처음으로 설정하는 데는 약간의 시간이 걸립니다. 연결이 설정된 후 연결은 이후 쿼리에서 다시 사용할 수 있도록 메모리에 풀링됩니다.

연결 풀링에 대한 자세한 내용은 아래 링크를 참조하십시오. https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling

앞에서 언급했듯이이 오류는 때로는 발생하지 않으며 항상 그런 것은 아니므로 일부 네트워크 및 연결 요소가있을 수 있습니다. SQL 연결의 기본 제한 시간은 15 초입니다. 30 초로 변경하면 효과가 있다고 생각합니다.


연결이 끊어 질 가능성이 완전히 있습니다. "분산 컴퓨팅의 허점". 네트워크 연결 문제 일 수 있습니다. 어떤 끝도 될 수 있습니다.

나는 추천 할 것이다 : (Azure에 당신의 기계를 위해 방호벽이 가능하다고 가정 할 때)

  1. 서버를 Ping하고 손실이 있는지 확인하십시오.

ping (서버) .database.windows.net

  1. tracert
  2. telnet은 친구가 될 수도 있습니다.

위의 세 가지는 문제가있는 곳을 정확하게 지적하는 데 도움이됩니다.

재시도 논리가 괜찮다고 생각합니다.

당신에 관해서

시간 초과 늘리기 쿼리가 오랜 시간이 걸릴 것이라고 확신하는 경우에만. 간단한 삽입의 경우 네트워크 연결이 될 수있는 시간 초과 문제를 늘려야합니다.

재시도 로직 이미 게시 된대로 이제는 활용할 수있는 프레임 워크의 일부이거나 생성 한 프레임 워크가 정상이어야합니다. 이상적으로는 연결 및 속도가 확실하더라도 리 트라이 로직을 사용하는 것이 좋습니다. 그냥 경우 :)


원격 서비스와 통신하는 모든 응용 프로그램은 일시적인 오류에 민감합니다.

다른 답변에서 언급했듯이 클라이언트 프로그램이 .NET Framework 클래스 System.Data.SqlClient.SqlConnection을 사용하여 SQL 데이터베이스에 연결하는 경우 연결을 사용할 수 있도록 .NET 4.6.1 이상 (또는 .NET Core)을 사용하십시오 재시도 기능.

SqlConnection 개체에 대한 연결 문자열을 작성할 때는 다음 매개 변수 사이에서 값을 조정하십시오.

ConnectRetryCount : 기본값은 1입니다. 범위는 0에서 255까지입니다.

ConnectRetryInterval : 기본값은 1 초입니다. 범위는 1에서 60까지입니다.

연결 제한 시간 : 기본값은 15 초입니다. 범위는 0에서 2147483647까지입니다.

특히, 선택한 값은 다음과 같은 평등을 만들어야합니다.

Connection Timeout = ConnectRetryCount * ConnectionRetryInterval

이제 옵션 2로 넘어갈 때, 앱에 맞춤 재시도 논리가 있으면 전체 재 시도 시간이 늘어납니다. 각 맞춤 재 시도마다 ConnectRetryCount 번 시도합니다. 예를 들어 ConnectRetryCount = 3이고 custom retry = 5 인 경우 15 회 시도합니다. 많은 재 시도가 필요하지 않을 수도 있습니다.

사용자 지정 재시도 대 연결 시간 제한 만 고려하는 경우 :

연결 시간 초과는 손실 된 네트워크 - 패킷 손실이 많은 네트워크 (예 : 셀룰러 또는 약한 WiFi) 또는 높은 트래픽로드로 인해 발생합니다. 그 중에서도 가장 좋은 전략을 선택하는 것은 당신에게 달려 있습니다.

다음 지침은 일시적인 오류를 해결하는 데 도움이됩니다.

  1. https://docs.microsoft.com/en-us/azure/sql-database/sql-database-connectivity-issues

  2. https://docs.microsoft.com/en-in/azure/architecture/best-practices/transient-faults


github.com/App-vNext/Polly 사용을 고려하십시오.

다음과 같은 간단한 코드를 사용할 수 있습니다.

RetryPolicy retryPolicy = Policy.Handle<Exception>()
            .WaitAndRetry(3, retryAttempt => 
TimeSpan.FromSeconds(retryAttempt));

var result = retryPolicy.Execute(() => someClass.DoSomething());

이렇게하면 최대 3 번까지 요청을 다시 시도합니다.







sqlconnection