我正在开发一个小应用程序,用于将大量数据从一个数据库转换并导入另一个数据库。为此,我使用Entity Framework和一些自定义扩展来一次提交一个项目页面,批量为1000左右。由于这可能需要一段时间,我还有兴趣确保如果在连接中出现打嗝时整个事情都不会停止。
我在this article之后选择了Transient Fault Handling Application块,它是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实例来实际测试重试策略。它几乎立即大便,这很奇怪。您可以看到我已将策略配置为以十秒为间隔再次尝试;无论是忽略间隔还是未能捕获错误。我怀疑后者,但我是新手,所以我真的不知道。
答案 0 :(得分:2)
我怀疑SqlAzureTransientErrorDetectionStrategy不包含您正在模拟的错误。此策略实现SQL Azure引发的特定错误。请查看此代码,了解此政策实施的错误:http://code.msdn.microsoft.com/Reliable-Retry-Aware-BCP-a5ae8e40/sourcecode?fileId=22213&pathId=1098196556
要处理您尝试捕获的错误,可以通过实现ITransientErrorDetectionStrategy接口来实现自己的策略。