Search code examples
c#azure-sql-databaseenterprise-library

SQL Azure retry logic using EnterpriseLibrary.TransientFaultHandling


Trying to implement a retry logic in a correct way, but couldn't find any good sample on how to properly leverage EnterpriseLibrary.TransientFaultHandling. So far I found two samples:

First - using ReliableSqlConnection & conn.Open(retryPolicy)

var retryStrategy = new Incremental(3, TimeSpan.FromMilliseconds(500), TimeSpan.FromSeconds(1));
var retryPolicy = new RetryPolicy<SqlDatabaseTransientErrorDetectionStrategy>(retryStrategy);

retryPolicy.ExecuteAction(() =>
{
    using (var conn = new ReliableSqlConnection(datasetConnectionString))
    {
        conn.Open(retryPolicy);

        using (var command = conn.CreateCommand())
        {
            command.CommandText = insertToParameters;
            command.CommandTimeout = 0;
            conn.ExecuteCommand(command);
        }
    }
});

and second - without the ReliableSqlConnection:

var retryStrategy = new Incremental(3, TimeSpan.FromMilliseconds(500), TimeSpan.FromSeconds(1));
var retryPolicy = new RetryPolicy<SqlDatabaseTransientErrorDetectionStrategy>(retryStrategy);

retryPolicy.ExecuteAction(() =>
{
    using (var conn = new SqlConnection(datasetConnectionString))
    {
        conn.Open();

        using (var command = conn.CreateCommand())
        {
            command.CommandText = insertToParameters;
            command.CommandTimeout = 0;
            conn.ExecuteCommand(command);
        }
    }
});

So few questions:

  1. which one is better and why?
  2. Is the external retryPolicy.ExecuteAction really needed - in older samples I see people retrying only individual actions, like OpenConnectionWithRetries, ExecuteCommandWithRetries, etc, but not the whole thing - I wonder if that is possible that the connection could potentially be closed between those retries.

Solution

  • Answering my own question:

    With newer transient error handling block, use SqlConnection with the provided extension methods, such as OpenWithRetry, etc.

    Use retryPolicy.ExecuteAction(() => {...}) whenever there is no support for the retry in the API, such as SqlBulkCopy, filling the dataset table, async methods etc. Make sure to re-open connection in the retry block. You still can use the SqlConnection with retry-able extension methods inside the retry block.

    UPDATE: edited to cause less confusion