[C#], Как ввести логику повторной попытки в LINQ к SQL для контакта с тайм-аутами?

Я должен найти способы добавить механизм повторной попытки к своим вызовам 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 достиг, но я не знаю, как и где бросить их соответственно :-)

Любой помогает ценивший.

5
задан Chris 7 April 2010 в 11:09
поделиться

2 ответа

Если вы получаете тайм-аут от базы данных, не очень вероятно, что она ответит своевременно несколькими милисекундами позже.

Повторные попытки в узком цикле, как вы предлагаете, скорее всего, ухудшат плохую ситуацию, потому что вы создадите чрезмерную нагрузку на сервер базы данных, а также завяжете поток в вызывающем коде. Безопаснее было бы ввести время ожидания между каждой повторной попыткой.

Для более сложных сценариев можно рассмотреть прогрессивный шаблон ожидания, когда в начале вы повторяете попытки чаще, а затем с все большими и большими интервалами, если вы все еще получаете тайм-ауты.

Возможно, вы также захотите рассмотреть шаблон проектирования Circuit Breaker из книги Release It! , а также многие другие паттерны и антипаттерны, описанные в этой книге.

Шаблон State хорошо подходит для реализации Circuit Breaker.

3
ответ дан 15 December 2019 в 00:55
поделиться

Лично я бы использовал здесь рекурсию. Это делает код более чистым, поскольку единственный «дополнительный код», который у вас есть, - это параметр функции. Например:

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;
}

Думаю, это идеальный пример рекурсии. Независимо от того, что вызывает это, не нужно беспокоиться о цикле, и это делает код НАМНОГО чище.

1
ответ дан 15 December 2019 в 00:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: