5

我已经阅读了有关TransactionScope这篇文章的内容,但我仍然不明白 2 件事:

  1. 什么时候SqlCommand.ExecuteNonQuery执行它直到scope.Complete()被调用才真正执行?如果是真的,那么范围内执行的所有操作都保留在哪里等待scope.Complete()scope.Rollback()
  2. 何时TransactionScope实例化它如何防止SqlCommand.ExecuteNonQuery被执行并等待scope.Complete()scope.Rollback()?它是否创建了一些“地方”并SqlCommand以某种方式知道它并将说明放在那里?
4

4 回答 4

6

[1] 执行 SqlCommand.ExecuteNonQuery 时,直到调用 scope.Complete() 才真正执行?

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

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

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

于 2012-07-19T10:55:58.210 回答
1

TransactionScope 隐藏了很多东西。

当您创建一个 TransactionScope 时,您在其中所做的一切都在数据库事务的上下文中。因此 SQL 语句将立即执行,但它们的影响将在事务内部,因此其他进程在事务提交之前不会知道它们已经发生。

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

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

注意 MSDTC 不限于数据库 - 请参阅此处了解更多信息。

于 2012-07-19T10:49:05.203 回答
0

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

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

事务本质上用在数据库中,但理论上,可以制作其他代码来支持它。

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

于 2012-07-19T10:51:02.023 回答
0

这可能会对您的问题有所帮助,您可以启用 MSDTC 跟踪以查看事务

有关详细信息,请参阅链接http://support.microsoft.com/kb/899115

希望这可以帮助..

于 2012-07-19T10:52:10.380 回答