如果外部事务范围未完成,内部事务范围会回滚吗?

Posted

技术标签:

【中文标题】如果外部事务范围未完成,内部事务范围会回滚吗?【英文标题】:Will an inner transaction scope roll back if the outer transaction scope doesn't complete? 【发布时间】:2011-05-28 17:29:09 【问题描述】:

我有两个事务范围,一个在另一个范围内。我很想知道内部事务范围在提交后是否会回滚,而外部事务范围没有完成。

【问题讨论】:

各种TransactionScopeOption选择的很好解释;终于有道理了:docs.microsoft.com/en-us/previous-versions/… 【参考方案1】:

这取决于您启动嵌套事务范围的范围选项。

如果你使用默认选项TransactionScopeOption.Required,那么嵌套作用域将与外部作用域在同一个事务中登记,因此当外部作用域回滚时,内部作用域也将被回滚,即使它调用了@987654322 @。

但是,如果您使用TransactionScopeOption.RequiresNew,则嵌套范围将开始自己的事务并与外部范围分开完成,因此即使外部范围回滚,它也不会回滚。

如果您使用TransactionScopeOption.Suppress,则嵌套范围将不参与外部事务,并将以非事务方式完成,因此不构成外部事务回滚时将回滚的工作的一部分。

【讨论】:

完美答案:) 如果将两个 Suppress 作用域嵌套在第三个外部作用域下怎么办?我是否应该在两个内部 Suppress 范围上调用 complete,这会完全干扰外部父范围吗?【参考方案2】:

由于它们是嵌套的,内部事务将回滚。

这不是全部,取决于您如何创建嵌套事务,但默认情况下,它会回滚。

This article 深入了解TransactionScope,应该会回答您的大部分问题。


分发与否无关紧要。

【讨论】:

@Frantisek 提到了分布式事务。我怎么知道我在使用分布式事务? 我想我错了。使用 TransactionScope,您可能不需要 dtc 来让它工作。阅读此msdn.microsoft.com/en-us/library/ms172152(v=vs.90).aspx:“虽然嵌套范围可以加入根范围的环境事务,但在嵌套范围内调用 Complete 对根范围没有影响。只有从根范围到最后一个嵌套范围的所有范围投票提交交易,交易是否会提交。” 我相信您知道这一点,但是在谈到 TransactionScope 时,术语“内部事务”和“嵌套事务”在恕我直言是不合适的,因为实际上没有嵌套事务,而只是嵌套了 TransactionScope。如果您选择 TransactionScopeOption.Required 它只是 1 个大事务,而使用 TransactionScopeOption.RequiresNew 则有 2 个完全独立的事务,但在(封闭的)嵌套事务的意义上它们不是嵌套的。【参考方案3】:

是的,你可以参考下面的代码。如果内部事务抛出错误,则以下代码将回滚外部事务范围,反之亦然。

   public bool rootMethod()
          using (var transaction = new(TransactionScopeOption.RequiresNew))
           try
           // your code here
           SomeController someController = new SomeController();
           var responseFromChildMethod = someController.childMethodWithTxn();

       // your logic here

       transaction.Complete();
       return true;
       
       catch(Exception ex)
       transaction.Dispose();
       return false;
       
     


SomeController.cs

public bool childMethodWithTxn()
  using(var newTransaction =  new TransactionScope())
    try
      //your code here
      newTransaction.Complete();
      return true;
    
    catch(Exception ex)
           newTransaction.Dispose();
           return false;
           

  

【讨论】:

如果 root 或 child 捕获异常,这将回滚

以上是关于如果外部事务范围未完成,内部事务范围会回滚吗?的主要内容,如果未能解决你的问题,请参考以下文章

这几个事务案例会回滚吗?最后一个90%的人判断错了...

这几个事务案例会回滚吗?最后一个90%的人判断错了...

java 事务方法调用非事务函数会回滚吗

如果在提交时抛出异常,C# TransactionScope 会回滚吗?

PHP PDO 执行失败时事务会回滚吗?

mysql事务未commit