다음을 통해 공유


SqlConnection.RetryLogicProvider 속성

정의

이 명령에 바인딩된 SqlRetryLogicBaseProvider 개체를 지정하는 값을 가져오거나 설정합니다.

public:
 property Microsoft::Data::SqlClient::SqlRetryLogicBaseProvider ^ RetryLogicProvider { Microsoft::Data::SqlClient::SqlRetryLogicBaseProvider ^ get(); void set(Microsoft::Data::SqlClient::SqlRetryLogicBaseProvider ^ value); };
[System.ComponentModel.Browsable(false)]
public Microsoft.Data.SqlClient.SqlRetryLogicBaseProvider RetryLogicProvider { get; set; }
public Microsoft.Data.SqlClient.SqlRetryLogicBaseProvider RetryLogicProvider { get; set; }
[<System.ComponentModel.Browsable(false)>]
member this.RetryLogicProvider : Microsoft.Data.SqlClient.SqlRetryLogicBaseProvider with get, set
member this.RetryLogicProvider : Microsoft.Data.SqlClient.SqlRetryLogicBaseProvider with get, set
Public Property RetryLogicProvider As SqlRetryLogicBaseProvider

속성 값

null(기본값)으로 설정하면 다시 시도 불가능한 기본 공급자가 적용됩니다.

특성

설명

연결을 열기 전에 이 속성의 값을 설정해야 합니다.

다시 시도 논리를 적용하려면 연결을 열기 전에 다음 단계를 수행합니다.

  1. 형식을 사용하여 구성 매개 변수를 SqlRetryLogicOption 정의합니다.
  2. SqlRetryLogicBaseProvider 클래스의 다음 정적 메서드 중 하나를 사용하여 을 만듭니다SqlConfigurableRetryFactory.
  3. 개체를 SqlRetryLogicBaseProvider 속성에 할당합니다 RetryLogicProvider .

참고

다시 시도 가능한 예외를 검색하는 것은 재시도 패턴의 중요한 부분입니다. 재시도 논리를 적용하기 전에 예외를 조사하고 시나리오에 가장 적합한 재시도 공급자를 선택하는 것이 중요합니다. 먼저 예외를 기록하고 일시적인 오류를 찾습니다.

참고

연결이 열릴 때마다 연결 제한 시간이 다시 시작됩니다. 이 두 작업 간에는 타이밍이 겹치지 않습니다.

참고

기본 재시도 논리 공급자는 애플리케이션 구성 파일에서 구성되지 않는 한 사용하도록 설정되지 않습니다. 자세한 내용은 구성 가능한 다시 시도 논리 및 구성 파일을 참조하세요.

예제

다음 샘플에서는 잘못된 데이터베이스에 대한 연결을 열어 데이터베이스 서비스를 일시적으로 사용할 수 없는 조건을 시뮬레이트합니다. 에서 연결을 설정하는 동안 데이터베이스를 SqlConnection 수동으로 만들어야 합니다.

using Microsoft.Data.SqlClient;

/// Detecting retriable exceptions is a vital part of the retry pattern.
/// Before applying retry logic it is important to investigate exceptions and choose a retry provider that best fits your scenario.
/// First, log your exceptions and find transient faults.
/// The purpose of this sample is to illustrate how to use this feature and the condition might not be realistic.
class RetryLogicSample
{
    private const string DefaultDB = "Northwind";
    private const string CnnStringFormat = "Server=localhost; Initial Catalog={0}; Integrated Security=true; pooling=false;";
    private const string DropDatabaseFormat = "DROP DATABASE {0}";

    // For general use
    private static SqlConnection s_generalConnection = new SqlConnection(string.Format(CnnStringFormat, DefaultDB));

    static void Main(string[] args)
    {
        // 1. Define the retry logic parameters
        var options = new SqlRetryLogicOption()
        {
            NumberOfTries = 5,
            MaxTimeInterval = TimeSpan.FromSeconds(20),
            DeltaTime = TimeSpan.FromSeconds(1)
        };

        // 2. Create a retry provider
        var provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);

        // define the retrying event to report the execution attempts
        provider.Retrying += (object s, SqlRetryingEventArgs e) =>
            {
                int attempts = e.RetryCount + 1;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine($"attempt {attempts} - current delay time:{e.Delay} \n");
                Console.ForegroundColor = ConsoleColor.DarkGray;
                if (e.Exceptions[e.Exceptions.Count - 1] is SqlException ex)
                {
                    Console.WriteLine($"{ex.Number}-{ex.Message}\n");
                }
                else
                {
                    Console.WriteLine($"{e.Exceptions[e.Exceptions.Count - 1].Message}\n");
                }

                // It is not a good practice to do time-consuming tasks inside the retrying event which blocks the running task.
                // Use parallel programming patterns to mitigate it.
                if (e.RetryCount == provider.RetryLogic.NumberOfTries - 1)
                {
                    Console.WriteLine("This is the last chance to execute the command before throwing the exception.");
                    Console.WriteLine("Press Enter when you're ready:");
                    Console.ReadLine();
                    Console.WriteLine("continue ...");
                }
            };

        // Open the general connection.
        s_generalConnection.Open();

        try
        {
            // Assume the database is being created and other services are going to connect to it.
            RetryConnection(provider);
        }
        catch
        {
            // exception is thrown if connecting to the database isn't successful.
            throw;
        }
    }

    private static void ExecuteCommand(SqlConnection cn, string command)
    {
        using var cmd = cn.CreateCommand();
        cmd.CommandText = command;
        cmd.ExecuteNonQuery();
    }

    private static void RetryConnection(SqlRetryLogicBaseProvider provider)
    {
        // Change this if you already have a database with the same name in your database.
        string dbName = "Invalid_DB_Open";

        // Create a connection to an invalid database.
        using var cnn = new SqlConnection(string.Format(CnnStringFormat, dbName));
        // 3. Assign the `provider` to the connection
        cnn.RetryLogicProvider = provider;
        Console.WriteLine($"Connecting to the [{dbName}] ...");
        // Manually execute the following command in SSMS to create the invalid database while the SqlConnection is attempting to connect to it.
        // >> CREATE DATABASE Invalid_DB_Open;
        Console.WriteLine($"Manually, run the 'CREATE DATABASE {dbName};' in the SQL Server before exceeding the {provider.RetryLogic.NumberOfTries} attempts.");
        // the connection tries to connect to the database 5 times
        Console.WriteLine("The first attempt, before getting into the retry logic.");
        cnn.Open();
        Console.WriteLine($"Connected to the [{dbName}] successfully.");

        cnn.Close();

        // Drop it after test
        ExecuteCommand(s_generalConnection, string.Format(DropDatabaseFormat, dbName));
        Console.WriteLine($"The [{dbName}] is removed.");
    }
}

적용 대상