嵌套/子TransactionScope回滚

我试图嵌套TransactionScopes(.net 4.0),因为它将在SQL Server中嵌套事务,但它看起来像它们的操作不同。 我希望我的子事务能够在它们失败时回滚,但允许父事务决定是否提交/回滚整个操作。 问题是第一次完成时,事务回滚。 我意识到完成不同于承诺。

我试图做的一个大大简化的例子:

static void Main(string[] args)
{
    using(var scope = new TransactionScope()) // Trn A
    {
        // Insert Data A

        DoWork(true);
        DoWork(false);

        // Rollback or Commit
    }
}

// This class is a few layers down
static void DoWork(bool fail)
{
    using(var scope = new TransactionScope()) // Trn B
    {
        // Update Data A

        if(!fail)
        {
            scope.Complete();
        }
    }
}

我不能使用Suppress或RequiresNew选项,因为Trn B依赖于Trn A插入的数据。如果我使用这些选项,则Trn B会被Trn A阻止。

任何想法如何让它起作用,或者甚至可以使用System.Transactions命名空间?

谢谢


你可能不会喜欢这个答案,但是...

在嵌套范围内投票

虽然嵌套作用域可以加入根作用域的环境事务,但在嵌套作用域中调用Complete并不会影响根作用域。 只有从根范围到最后一个嵌套范围的所有范围投票才能提交事务,才会提交事务。

(使用事务范围实现隐式事务)

不幸的是, TransactionScope类没有提供任何机制(我知道)分离工作单元。 这是全部或没有。 你可以通过使用TransactionScopeOption.Suppress来防止在特定的工作单元上发生任何TransactionScopeOption.Suppress ,但这可能不是你想要的,因为你将失去该范围内的任何东西的原子性。

使用TransactionScope时,只有一个“环境” TransactionScope 。 一旦TransactionScope被处置或者在没有Complete被执行的情况下被收集,整个环境事务就会被回滚; 就是这样,游戏结束了。

实际上,SQL Server根本不支持真正的嵌套事务,虽然可以(尽管有点不直观)通过适当使用SAVE TRAN语句来实现相同的最终结果。 如果您需要这种特殊行为,将这一逻辑重新实现为存储过程(或其中几个)可能是您的最佳选择。

链接地址: http://www.djcxy.com/p/49971.html

上一篇: Nested/Child TransactionScope Rollback

下一篇: Image Cropping Issue for Cropping an Image