如何在不同的上下文中使用事务?

Ego*_*tev 5 c# entity-framework transactions entity-framework-6

在我的应用程序中,我有这样的方法:

public static bool DoLargeOperation()
{
    bool res = true;

    res = res && DoFirstSubOperation();
    res = res && DoSecondSubOperation();
    res = res && DoThirdSubOperation();

    return res;
}
Run Code Online (Sandbox Code Playgroud)

每个内部方法如下所示:

public static bool DoFirstSubOperation()
{
    using (var context = new EntityFrameworkContext())
    {
        // data modification.
        context.SaveChanges();
    }
}
Run Code Online (Sandbox Code Playgroud)

例如,DoFirstSubOperation()DoSecondSubOperation()成功完成,但DoThirdSubOperation()失败.如何回滚前两个函数所做的更改?

这种方法没有带来结果:

using (var transaction = new TransactionScope())
{
    res = res && DoFirstSubOperation();
    res = res && DoSecondSubOperation();
    res = res && DoThirdSubOperation();
}
Run Code Online (Sandbox Code Playgroud)

我看到的唯一解决方案是定义上下文,如下所示:

public static bool DoLargeOperation()
{
    bool res = true;

    using (var context = new EntityFrameworkContext())
    {
        using (var transaction = context.Database.BeginTransaction())
        {

            res = res && DoFirstSubOperation(context);
            res = res && DoSecondSubOperation(context);
            res = res && DoThirdSubOperation(context);
            if (res)
            {
                transaction.Commit();
            }
            else
            {
                transaction.Rollback();
            }
        }
    }

    return res;
}
Run Code Online (Sandbox Code Playgroud)

但这样做是否可以接受?还是有其他解决方案吗?

Phi*_*ght 5

是的,这是正确的模式.将上下文传递给方法允许方法在多个位置重用,因为上下文和事务将由调用者管理.

虽然,您可能希望在第一个方法失败后停止处理后续方法.您也可能希望将调用包装在try/catch中,以便任何异常都允许回滚正确发生...

try
{
    res = DoFirstSubOperation(context);
    if (res) 
        res = DoSecondSubOperation(context);
    if (res) 
        res = DoThirdSubOperation(context);    

    if (res)
        transaction.Commit();
    else
        transaction.Rollback();
}
catch
{
    transaction.Rollback();
}
Run Code Online (Sandbox Code Playgroud)

如果您的子方法已经处理异常,那么您可以放弃try/catch.