0

我正在开发一个小型应用程序,用于将大量数据从一个数据库转换和导入到另一个数据库。为此,我使用实体框架和一些自定义扩展来一次提交一页项目,批量为 1000 个左右。由于这可能需要一段时间,我也有兴趣确保如果在运行时连接出现问题,整个事情不会停止。

在本文之后,我选择了 Enterprise Library 5.0 中的瞬态故障处理应用程序块(请参阅案例 2:具有事务范围的重试策略)。这是我以 ObjectContext 扩展形式实现的示例,它使用专注于 Sql Azure 内容的重试策略将对象添加到上下文并尝试保存它们:

public static void AddObjectsAndSave<T>(this ObjectContext context, IEnumerable<T> objects)
    where T : EntityObject
{
    if(!objects.Any())
        return;

    var policy = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>
        (10, TimeSpan.FromSeconds(10));
    var tso = new TransactionOptions();
    tso.IsolationLevel = IsolationLevel.ReadCommitted;

    var name = context.GetTableName<T>();

    foreach(var item in objects)
        context.AddObject(name, item);


    policy.ExecuteAction(() =>
    {
        using(TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, tso))
        {
            context.SaveChanges();

            ts.Complete();
        }
    });
}

代码运行良好,直到我通过在运行时暂停本地 Sql Server 实例来实际测试重试策略。它几乎立即便便,这很奇怪。您可以看到我已将策略配置为每隔 10 秒重试一次;它要么忽略间隔,要么未能捕获错误。我怀疑是后者,但我是新手,所以我真的不知道。

4

1 回答 1

2

我怀疑 SqlAzureTransientErrorDetectionStrategy 不包括您正在模拟的错误。此策略实施 SQL Azure 引发的特定错误。查看此代码以了解此策略实现了哪些错误:http ://code.msdn.microsoft.com/Reliable-Retry-Aware-BCP-a5ae8e40/sourcecode?fileId=22213&pathId=1098196556

要处理您试图捕获的错误,您可以通过实现 ITransientErrorDetectionStrategy 接口来实现自己的策略。

于 2012-07-09T13:36:26.780 回答