【问题标题】:What happens to Transaction if TransactionScope.Complete not called at the end of the Using block如果在 Using 块的末尾没有调用 TransactionScope.Complete,事务会发生什么
【发布时间】:2018-08-27 05:10:18
【问题描述】:

我正在使用 SQL Server 2012,并且在 TransactionScope Using 块中有多个 SQL 连接到同一个数据库。但是,如果第一次更新 SQL 操作没有产生所需的输出,那么我将跳过对 SQL 操作的下一次调用,并在 Using 块的末尾调用未调用的TransactionScope.Complete。

【问题讨论】:

标签: c# sql-server ado.net transactionscope


【解决方案1】:

你需要的大部分信息都在这里Completing a transaction scope

当您的应用程序完成它想要在一个 交易,你应该只调用一次 Complete 方法来通知 可以接受提交的事务管理器 交易。调用 Complete 是非常好的做法 using 块中的最后一条语句。

未能调用此方法会中止事务,因为 事务管理器将此解释为系统故障或等效 在事务范围内抛出异常。然而, 调用此方法并不能保证交易会 坚定的。它只是通知事务管理器的一种方式 你的状态。调用 Complete 方法后,就不能再 使用 Current 属性访问环境事务,以及 尝试这样做会导致抛出异常。

【讨论】:

    【解决方案2】:

    未能调用事务完成将导致事务中止,这就是为什么调用transaction.complete();是一个非常好的parcitce的原因

    会发生什么,事务管理器会将其解释为系统故障并抛出异常(发生在我身上一次,不好),但是这是一个很大的然而,它不承诺事务将被提交,因此您也必须调用 commit。

    例如:

           using (TransactionScope scope = new TransactionScope())
            {
                using (SqlConnection connection1 = new SqlConnection(connectString1))
                {
                    // Opening the connection automatically enlists it in the 
                    // TransactionScope as a lightweight transaction.
                    connection1.Open();
    
                    // Create the SqlCommand object and execute the first command.
                    SqlCommand command1 = new SqlCommand(commandText1, connection1);
                    returnValue = command1.ExecuteNonQuery();
                    writer.WriteLine("Rows to be affected by command1: {0}", returnValue);
    
                    // If you get here, this means that command1 succeeded. By nesting
                    // the using block for connection2 inside that of connection1, you
                    // conserve server and network resources as connection2 is opened
                    // only when there is a chance that the transaction can commit.   
                    using (SqlConnection connection2 = new SqlConnection(connectString2))
                    {
                        // The transaction is escalated to a full distributed
                        // transaction when connection2 is opened.
                        connection2.Open();
    
                        // Execute the second command in the second database.
                        returnValue = 0;
                        SqlCommand command2 = new SqlCommand(commandText2, connection2);
                        returnValue = command2.ExecuteNonQuery();
                        writer.WriteLine("Rows to be affected by command2: {0}", returnValue);
                    }
                }
    
                // The Complete method commits the transaction. If an exception has been thrown,
                // Complete is not  called and the transaction is rolled back.
                scope.Complete();
    
            }
    

    提交将发生在 using 块的末尾,即 如果 TransactionScope 对象最初创建了工作。否则,提交将发生只要调用commit 行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-03
      • 1970-01-01
      • 1970-01-01
      • 2011-11-05
      • 2012-08-03
      • 2011-03-15
      相关资源
      最近更新 更多