使用EnterpriseLibrary.TransientFaultHandling进行SQL Azure重试逻辑

3
尝试以正确的方式实现重试逻辑,但无法找到任何关于如何正确利用EnterpriseLibrary.TransientFaultHandling的好示例。目前我找到了两个示例:
第一个 - 使用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);
        }
    }
});

其次 - 不使用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);
        }
    }
});

所以有几个问题:

  1. 哪一个更好,为什么?
  2. 外部的retryPolicy.ExecuteAction是否真的需要 - 在旧的示例中,我看到人们只重试单个操作,比如OpenConnectionWithRetriesExecuteCommandWithRetries等,但不是整个过程 - 我想知道这样做是否可能导致连接在这些重试之间被关闭。
2个回答

3

回答我的问题:

使用较新的瞬态错误处理块,使用SqlConnection提供的扩展方法,例如OpenWithRetry等。

每当API不支持重试(如SqlBulkCopy、填充数据集表、异步方法等)时,请使用retryPolicy.ExecuteAction(() => {...})。确保在重试块中重新打开连接。在重试块中仍然可以使用带有可重试扩展方法的SqlConnection。

更新:编辑以减少混淆


1
最好的模式是RetryPolicy.ExecuteAction(() =>。将您的数据库交互封装到ExecuteAction() lambda中,并将其视为工作单元。这将保持与ADO.Net API的最高兼容性。它还允许您使用ADO.Net中的新异步方法。
ReliableSQLConnection主要用于向后兼容。

我不会将ReliableSqlConnection称为过时的 - 它在可重试的调用中具有其自身的用途,您不必自己重新打开连接。 - Mikl X

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接