我读过关于TransactionScope和this的文章,但我仍然不明白两件事:
SqlCommand.ExecuteNonQuery
时,在调用scope.Complete()
之前它并没有真正执行?如果是真的,那么哪里范围内执行的所有操作都会保留并等待scope.Complete()
或scope.Rollback()
?TransactionScope
时如何阻止执行SqlCommand.ExecuteNonQuery
并等待scope.Complete()
或scope.Rollback()
?它是否会创建一些“地点”并且SqlCommand
以某种方式知道它并将指令放在那里?答案 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)