Я пишу приложение для 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;
}
Последнее решение выше описано как http://blogs.msdn.com/b/appfabriccat/archive/2010/10/28/best-practices-for-handling-transient-conditions-in-sql-azure-client-applications.aspx Рекомендации по обработке переходных условий в клиентском приложении SQL Azure (расширенные шаблоны использования).
В то время как это шаг вперед, я все равно должен помнить, что следует использовать класс RetryPolicy всякий раз, когда я хочу получить доступ к базе данных через Entity Framework. В команде из нескольких человек это легко пропустить. Кроме того, приведенный выше код немного беспорядочен, по моему мнению.
То, что я хотел бы, это способ принудительного применения повторных попыток всегда использовать все время. Библиотека Transient Fault Handling содержит класс ReliableSQLConnection, но я не могу найти способ использовать его с Entity Framework.
Любые хорошие предложения по этой проблеме?