在连接数据库失败时实施连接重试策略

Implementing connection retry policy on failure to connect with database

我的数据库在云端,即 Azure,所以有时我会遇到与网络相关的错误,如下所示:

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

我决定在一段时间后使用Polly重试连接尝试,但我不确定我是否以正确的方式使用它:

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;
                RetryPolicy retryPolicy = Policy
                      .Handle<DbException>()
                      .WaitAndRetry(new[]
                      {
                        TimeSpan.FromSeconds(3),
                        TimeSpan.FromSeconds(6),
                        TimeSpan.FromSeconds(9)
                      });
                retryPolicy.Execute(() => ConnectionManager.OpenConnection(cn));
                using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                { 
                   //code
                }
            }
        }
}

public class ConnectionManager
{
        public static void OpenConnection(DbConnection cn)
        {
            try
            {
                cn.Open();
                return;
            }
            catch(DbException ex)
            {
                throw ex;
            }
        }
    }

根据我的理解,Polly 会像这样工作:

第一次尝试:等待 3 秒,然后再次调用 ConnectionManager.OpenConnection(cn)

第二次尝试:等待 6 秒,然后在 DbException

上再次调用 ConnectionManager.OpenConnection(cn)

第三次尝试: 等待 9 秒,然后在 DbException

上再次调用 ConnectionManager.OpenConnection(cn)

但是如果DbException再次出现怎么办?它会处理或发送到我的 catch 子句来结束 Process 方法吗?

我不确定自己是否理解正确并正确执行。

我将不胜感激:)

回复:

what if DbException occurs again? Will [Polly] process or send to my catch clause wrapping up Process method?

Polly wiki for Retry 状态:

If the action throws a handled exception, the policy:

  • Counts the exception
  • Checks whether another retry is permitted.
    • If not, the exception is rethrown and the policy terminates.

一个simple example可以证明这一点。