Я должен найти способы добавить механизм повторной попытки к своим вызовам DB в случае тайм-аутов, LINQ к SQL используется для вызова некоторого sprocs в моем коде...
using (MyDataContext dc = new MyDataContext())
{
int result = -1; //denote failure
int count = 0;
while ((result < 0) && (count < MAX_RETRIES))
{
result = dc.myStoredProc1(...);
count++;
}
result = -1;
count = 0;
while ((result < 0) && (count < MAX_RETRIES))
{
result = dc.myStoredProc2(...);
count++;
}
...
...
}
Не уверенный, если код выше является правильным или изложил какие-либо сложности.
Будет хорошо выдать исключение после того, как MAX_RETRIES достиг, но я не знаю, как и где бросить их соответственно :-)
Любой помогает ценивший.
Если вы получаете тайм-аут от базы данных, не очень вероятно, что она ответит своевременно несколькими милисекундами позже.
Повторные попытки в узком цикле, как вы предлагаете, скорее всего, ухудшат плохую ситуацию, потому что вы создадите чрезмерную нагрузку на сервер базы данных, а также завяжете поток в вызывающем коде. Безопаснее было бы ввести время ожидания между каждой повторной попыткой.
Для более сложных сценариев можно рассмотреть прогрессивный шаблон ожидания, когда в начале вы повторяете попытки чаще, а затем с все большими и большими интервалами, если вы все еще получаете тайм-ауты.
Возможно, вы также захотите рассмотреть шаблон проектирования Circuit Breaker из книги Release It! , а также многие другие паттерны и антипаттерны, описанные в этой книге.
Шаблон State хорошо подходит для реализации Circuit Breaker.
Лично я бы использовал здесь рекурсию. Это делает код более чистым, поскольку единственный «дополнительный код», который у вас есть, - это параметр функции. Например:
private MyResult Foo(MyParameters mp, int repeatCall)
{
var result = null;
try
{
result = mp.dc.myStoredProc(...);
}
catch (MyException err)
{
if (repeatCall > 0)
{
result = Foo(mp, repeatCall - 1);
}
else
{
throw;
}
}
return result;
}
Думаю, это идеальный пример рекурсии. Независимо от того, что вызывает это, не нужно беспокоиться о цикле, и это делает код НАМНОГО чище.