我正在为
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的失败(重试是浪费时间,如果它是一个主要的关键违规),我将立即重试,没有任何暂停等等.
我的下一步是开始使用Microsoft的瞬态故障处理库.它包含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客户端应用程序(高级使用模式部分)中处理瞬态条件的http://blogs.msdn.com/b/appfabriccat/archive/2010/10/28/best-practices-for-handling-transient-conditions-in-sql-azure-client-applications.aspx最佳实践.
这是向前迈进的一步,但是当我想通过实体框架访问数据库时,我仍然需要记住使用RetryPolicy类.在几个人的团队中,这是一件很容易错过的事情.此外,上面的代码在我看来有点凌乱.
我想要的是一种强制执行重试的方法,始终都是使用的.瞬态故障处理库包含一个名为ReliablesqlConnection的类,但我找不到使用实体框架的方法.
对这个问题有什么好的建议?