Как организовать транзакции? - PullRequest
3 голосов
/ 20 апреля 2011

У меня есть сервисы, вызванные методом Guardian, для которого TransactionScope открыт для каждого запроса, и завершите эту транзакцию, если все в порядке:

void ExecuteWorker(...)
{
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        ...CallLogicMethods...

        scope.Complete();
    }
}

Один из методов взаимодействует со службой «Внешний», и в случае сбоя этого взаимодействия все мои транзакции также не выполняются. В результате я не сохраняю необходимые данные (рассчитанные до запроса во внешнюю службу.

void DoLogic1(...)
{
    CalculateSomeData(...);
    SaveCalculatedData(...);

    DoRequestToExternalService(...);
}

Как лучше всего решить эту проблему?

Приложение написано с использованием C #, .NET 4.0, MS SQL 2008.

Сам вижу два решения

  1. Использование try / catch:

    void DoLogic11 (...) { CalculateSomeData (...); SaveCalculatedData (...);

    try
    {
        DoRequestToExternalService(...);
    }
    catch(Exception exc)
    {
        LogError(...);
    }
    

    }

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

  1. Использование 'Nested transcation', но я не уверен, как это работает.

Вот мое видение, оно должно быть:

void DoLogic12(...)
{
    using (TransactionScope scopeNested = new TransactionScope(TransactionScopeOption.Suppress))
    {
        CalculateSomeData(...);
        SaveCalculatedData(...);
        scopeNested.Complete()
    }

    DoRequestToExternalService(...);        
}

Я реализовал это, пытался использовать, но кажется, что вложенный транскрипция фиксируется только в том случае, если внешний также фиксируется.

Пожалуйста, сообщите.

Ответы [ 2 ]

1 голос
/ 25 апреля 2011

Я не уверен, что правильно понял. Можете ли вы поместить все свои логические методы в одну попытку? Каждый вызов представляет собой отдельную транзакцию с использованием TransactionScopeOption.RequiresNew

void DoLogic1(...)
{
    try
    {
        CalculateSomeData(...);
        SaveCalculatedData(...);
        DoRequestToExternalService(...);
    }
    catch(Exception ex)
    {
        LogException(...)
        throw;
    }
}

Но я хотел бы передать ошибку снаружи как исключение (для регистрации и т. д.).

Можете ли вы использовать throw ?

0 голосов
/ 10 мая 2011

Я решил изменить свой метод ExecuteWorker для условного создания транзакции. Поэтому я могу создать транзакцию в самом методе DoLogicX.

...