在提交或回滚作用域之前,TransactionScope块中的所有代码如何才真正执行?

时间:2012-07-19 10:44:41

标签: c# .net transactions transactionscope

我读过关于TransactionScopethis的文章,但我仍然不明白两件事:

  1. 执行SqlCommand.ExecuteNonQuery时,在调用scope.Complete()之前它并没有真正执行?如果是真的,那么哪里范围内执行的所有操作都会保留并等待scope.Complete()scope.Rollback()
  2. 实例化TransactionScope时如何阻止执行SqlCommand.ExecuteNonQuery并等待scope.Complete()scope.Rollback()?它是否会创建一些“地点”并且SqlCommand以某种方式知道它并将指令放在那里?

4 个答案:

答案 0 :(得分:6)

  

[1]当执行SqlCommand.ExecuteNonQuery时,在调用scope.Complete()之前它并没有真正执行?

不,这不正确。您的命令在您调用ExecuteNonQuery的行上执行。然而,知道 存储所有更改是有趣的。更改不直接转到服务器端的受影响的表,而是将更改存储在临时位置(再次在服务器端),这将导致第二个问题的答案

  

[2]当实例化TransactionScope时,它如何阻止执行SqlCommand.ExecuteNonQuery并等待scope.Complete()或scope.Rollback()?

它不会阻止,执行 操作,但由于操作的结果存储在临时位置,您必须将这些更改与主表 - scope.Commit()或丢弃这些更改 - scope.Rollback()(或用于丢弃特定数据库数据提供程序中的更改的任何内容)

答案 1 :(得分:1)

TransactionScope隐藏了很多内容。

创建TransactionScope时,您在其中执行的所有操作都在数据库事务的上下文中。因此,SQL语句将立即执行,但它们的效果将在事务中,以便其他进程在事务提交之前不会意识到它们已经发生。

如果您只使用单个数据库,则会针对该数据库打开并提交事务,或根据您是否.Complete()回滚事务。 此外,如果在TransactionScope的上下文中发生异常,则回滚事务。

如果您正在使用多个数据库,则会在每个数据库中创建一个事务,Microsoft分布式事务处理协调器(MSDTC)将管理整个事务。当你.Complete()时,MSDTC将指示每个单独的事务提交。

注意MSDTC不仅限于数据库 - 有关详细信息,请参阅here

答案 2 :(得分:0)

事务范围不会阻止代码执行,它会阻止事务提交。所以在SqlCommand.ExecuteNonQuery的情况下,因为它在事务中,SqlCommand查看事务协调器并看到它是在事务内部调用的,所以当它连接到SQL Server时,事务被维护,因此SQL将数据写入数据库,但除非事务已提交(或有人进行“脏读”),否则无法读取数据。如果从未调用complete,那么当TransactionScope被释放时,它将被回滚,并且SQL可以撤消插入(或其他任何操作)。

任何使用事务(例如其他数据库技术)的东西都需要实现其.Net代码来支持事务。

事务主要用于数据库,但从理论上讲,可以使用其他代码来支持它。

但是,要回答您的问题,在调用Complete()方法之前,代码不会停止,它会在事务中运行。

答案 3 :(得分:0)

这可能有助于您解决问题,以便跟踪MSDTC查看交易

请参阅链接了解详细信息http://support.microsoft.com/kb/899115

希望这会有所帮助..