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

时间:2015-03-03 04:23:04

标签: 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;
}

每个内部方法都是这样的:

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

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

这种方法没有带来结果:

using (var transaction = new TransactionScope())
{
    res = res && DoFirstSubOperation();
    res = res && DoSecondSubOperation();
    res = res && DoThirdSubOperation();
}

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

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

但这样做是否可以接受?还是有另一种解决方案吗?

1 个答案:

答案 0 :(得分: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();
}

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