如何组织交易?

3

我已经通过“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. Using try/catch:

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

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

    }

这种方法的缺点是我将异常隐藏了,但我希望将错误作为异常传递给外部(以便记录等)。

  1. 使用“嵌套事务”,但我不确定它是如何工作的。

这是我的设想:

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

    DoRequestToExternalService(...);        
}

我已经实现了这个功能,尝试使用了一下,但似乎只有在外部事务提交时嵌套的事务才会被提交。

请给予建议。


我不确定我是否正确理解了您的问题... 无论如何,请考虑您也可以使用RequiresNew标志创建事务。 在这种情况下,事务会立即提交,而不必等待外部事务。 - Davide Icardi
2个回答

1

我不确定我是否正确理解了它。您能否将所有逻辑方法放在一个 try-catch 中?每个调用都使用 TransactionScopeOption.RequiresNew 进行单独的事务处理。

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

但我想将错误作为异常传递到外部(以便记录等)。

你可以使用throw吗?


如果我执行'throw',那么我的外部事务将会失败。请查看方法'ExecuteWorker' - 如果内部发生任何异常,事务将不会被提交...似乎我的外部事务范围的想法不起作用...我不需要总是创建它... - Budda

0

我决定将我的“ExecuteWorker”方法更改为有条件地创建事务。因此,我能够在“DoLogicX”方法本身中创建事务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接