使用Entity Framework与SQL Azure - 可靠性

14

我正在编写一个针对Windows Azure的应用程序。我正在使用Entity Framework来访问SQL Azure。由于SQL Azure中的限制和其他机制,如果一个SQL语句执行失败,我需要确保我的代码执行重试操作。我正在尝试想出一种可靠的方法来实现这个目标。

(在下面的代码中,ObjectSet返回我的EFContext.CreateObjectSet())

假设我有以下函数:

  public Product GetProductFromDB(int productID)
  {
     return ObjectSet.Where(item => item.Id = productID).SingleOrDefault();
  }

现在,这个函数没有重试机制,在SQL Azure中迟早会失败。一个天真的解决方案是像这样做:

  public Product GetProductFromDB(int productID)
  {
     for (int i = 0; i < 3; i++)
     {
        try
        {
           return ObjectSet.Where(item => item.Id = productID).SingleOrDefault();
        }
        catch
        {

        }
     }
  }

当然,这种方法也有一些缺点。无论出现什么SQL失败问题(例如主键冲突),我都会进行重试(而重试可能是浪费时间的),我会立即重试而不进行任何暂停等等。

我的下一步是开始使用微软的瞬态错误处理库。它包含RetryPolicy,使我能够将重试逻辑与实际查询代码分开:

  public Product GetProductFromDB(int productID)
  {
     var retryPolicy = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(5);

     var result = _retryPolicy.ExecuteAction(() =>
        {
           return ObjectSet.Where(item => item.Id = productID).SingleOrDefault;
        });

     return result;
  }
最新的解决方案描述为一个应用于SQL Azure客户端应用程序中处理瞬态条件的最佳实践,详细信息请参考此处(高级使用模式部分)。
虽然这是一种进步,但我仍然需要记得每当想要通过实体框架访问数据库时使用RetryPolicy类。在一个由多个人组成的团队中,这是很容易忽视的事情。此外,上面的代码在我看来有点杂乱无章。
我想要的是一种方法,可以强制始终使用重试。Transient Fault Handling库包含一个名为ReliableSQLConnection的类,但我找不到一种与Entity Framework一起使用的方式。
对此问题有任何好的建议吗?
2个回答

7

这个回答并没有回答问题 - 问题是是否有可能不必记住为每个调用使用RetryPolicy。您提供的链接并没有展示如何做到这一点,事实上建议您需要包装每个调用。 - Robert Moore

3
如果您使用的是Entity Framework 6(目前处于alpha版本),那么就可以通过一些内置支持来对Azure SQL数据库进行瞬态重试,只需进行一点点配置:http://entityframework.codeplex.com/wikipage?title=Connection%20Resiliency%20Spec 我创建了一个库,允许您配置Entity Framework以使用Fault Handling块进行重试,而无需更改每个数据库调用 - 通常您只需要更改配置文件和可能的一两行代码。
这使您能够将其用于Entity Framework https://github.com/robdmoore/ReliableDbProvider

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