Search code examples
c#sql-serverconnection-stringpollytransient-failure

Implementing connection retry policy on failure to connect with database


I have my database on cloud i.e Azure so sometimes I get network related error like this:

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)

I have decide to use Polly to retry connection attempt after some time, but I am not sure whether I have used it in the right way or not :

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;
            }
        }
    }

As per my understanding Polly will work something like this :

1st attempt : Wait 3 seconds then call ConnectionManager.OpenConnection(cn) again

2nd attempt : Wait 6 seconds then call ConnectionManager.OpenConnection(cn) again on DbException

3rd attempt : Wait 9 seconds then call ConnectionManager.OpenConnection(cn) again on DbException

But what if DbException occurs again? Will it process or send to my catch clause wrapping up Process method?

I am not sure whether I have understood it properly and implemented it correctly.

I will appreciate any help :)


Solution

  • Re:

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

    The Polly wiki for Retry states:

    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.

    A simple example can demonstrate this.