如果在Using块的结尾没有调用TransactionScope.Complete,事务会发生什么?

5

我正在使用SQL Server 2012,同一个数据库内有多个SQL连接在TransactionScope的Using块中。但是,如果第一个更新SQL操作没有得到期望的输出,则我会跳过下一个调用SQL操作,并且在Using块结束时也不会调用TransactionScope.Complete


1
https://learn.microsoft.com/en-us/dotnet/framework/data/transactions/implementing-an-implicit-transaction-using-transaction-scope#completing-a-transaction-scope - TheGeneral
谢谢@TheGeneral。你能发表一个答案,这样我就可以接受它了。 - Bhalchandra K
2个回答

4
您需要的大部分信息都在这里很好地排列了 完成事务范围 当您的应用程序在一个事务中完成所有工作后,应该只调用一次Complete方法来通知事务管理器可以提交事务。将调用Complete作为using块中的最后一个语句是非常好的实践。 没有调用此方法会中止事务,因为事务管理器将其解释为系统故障或等同于在事务范围内抛出异常。但是,调用此方法并不保证事务将被提交。它只是一种通知事务管理器您的状态的方式。在调用Complete方法之后,您不能再使用Current属性访问环境事务,并且尝试这样做将导致抛出异常。

2

未调用事务完成将导致事务中止,这就是为什么调用 transaction.complete(); 是一种非常好的实践。

会发生的情况是,事务管理器将其解释为系统故障并抛出异常(我曾经遇到过这种情况,很不好),但是,需要注意的是,这并不保证事务将被提交,因此您还需要调用 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();

        }

提交将在使用块的末尾发生,即如果TransactionScope对象最初创建了工作。否则,提交将发生无论何时调用commit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接