代码之家  ›  专栏  ›  技术社区  ›  Neil Barnwell

即使未调用System.Transactions.TransactionScope.Commit(),也已提交数据

  •  4
  • Neil Barnwell  · 技术社区  · 15 年前

    在什么情况下代码可以包装在 System.Transactions.TransactionScope 仍然提交,即使抛出了异常,并且最外层的作用域从未调用过提交?

    有一个顶级方法 using (var tx = new TransactionScope()) ,并调用同时使用 TransactionScope 以同样的方式。

    我正在使用类型化数据集和关联的TableAdapter。可能是由于某种原因适配器中的命令没有登记吗?你们中有人知道如何检查他们是否在环境事务范围内登记吗?

    3 回复  |  直到 11 年前
        1
  •  7
  •   Neil Barnwell    15 年前

    答案是因为我创造了 TransactionScope 对象 之后 这个 SqlConnection 对象。

    我从这里搬了过来:

    using (new ConnectionScope())
    using (var transaction = new TransactionScope())
    {
        // Do something that modifies data
    
        transaction.Complete();
    }
    

    对此:

    using (var transaction = new TransactionScope())
    using (new ConnectionScope())
    {
        // Do something that modifies data
    
        transaction.Complete();
    }
    

    现在它开始工作了!

    所以这个故事的寓意是 交易范围 第一 .

        2
  •  2
  •   Community CDub    8 年前

    最明显的情况是( RequiresNew /NULL(空) Suppress )事务是显式指定的-但也有一个超时/解除绑定故障,可能导致连接错过事务。看到这个 earlier post (修复只是连接字符串更改),或者 full details .

        3
  •  0
  •   owerkop    11 年前

    注意如何 TransactionScope 作品:
    它设置属性 System.Transactions.Transaction.Current 在使用范围的开始,然后在使用范围结束时将其设置回以前的值。

    前一个值取决于给定范围的声明位置。它可以在另一个范围内。


    您可以这样修改代码:

    using (var sqlConnection = new ConnectionScope())
    using (var transaction = new TransactionScope())
    {
        sqlConnection.EnlistTransaction(System.Transactions.Transaction.Current);
        // Do something that modifies data
        transaction.Complete();
    }
    

    我向那些代码更复杂并且不能简单地将代码更改为先打开DB连接的用户展示了这种可能性。