无法连接数据库时实施连接重试策略

时间:2018-04-23 14:31:48

标签: c# sql-server connection-string polly transient-failure

我的数据库在云上,即Azure,所以有时我会收到与此类似的网络错误:

  

建立与SQL Server的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确,以及SQL Server是否配置为允许远程连接。 (提供者:命名管道提供程序,错误:40 - 无法打开与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秒,然后再次ConnectionManager.OpenConnection(cn)

再次致电DbException

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

再次致电DbException

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

我不确定我是否理解它并正确实施。

我将不胜感激任何帮助:)

1 个答案:

答案 0 :(得分:1)

回复:

  

如果再次发生DbException怎么办?将[Polly]处理或发送到我的catch子句包装Process方法吗?

Polly wiki for Retry州:

  

如果操作引发处理的异常,则为策略:

     
      
  • 计算例外
  •   
  • 检查是否允许其他重试。      
        
    • 如果没有,则重新抛出异常并且策略终止。
    •   
  •   

simple example可以证明这一点。