SQL Server 触发器的隔离级别 / 范围文档

6

我一直在寻找有关SQL Server触发器隔离级别(或并发性或范围...我不确定应该如何精确地称呼它)的权威文档。

我找到了以下来源,这些来源表明我所相信的是正确的(也就是说,两个用户执行对同一张表的更新 - 即使是相同的行 - 那么独立和隔离的触发器将被执行):

第一个问题本质上是我试图找到答案的同一个问题,但给出的答案没有提供任何来源。第二个问题也接近于这个问题,答案相同,但同样没有提供来源。有人能告诉我在哪里可以找到相关文档来支持这些说法吗?谢谢!

是的。一个用户将无法同时查看第二个用户的数据。当然,这假设触发器没有使用“读取未提交”或“无锁”。这很容易证明。创建一个带有触发器的表。然后在SSMS中打开1个选项卡并开始事务并插入数据。不要提交该事务,并在第二个选项卡中执行相同的操作。第二个选项卡无法查看选项卡1中未提交的数据。 - Sean Lange
我不确定你能否找到任何官方文档以你想要的形式明确说明这一点。但是,如果不是这样的话,触发器开发将会变得非常混乱,这一点很容易想象。 - Damien_The_Unbeliever
@Damien_The_Unbeliever 我链接了一些官方文件,其中提供了一些相关信息。 - Solomon Rutzky
1个回答

11

好的,隔离级别和作用域是两个非常不同的概念。

隔离级别
触发器在事务中运行。默认情况下,该事务应该使用READ COMMITTED的默认隔离级别。然而,如果调用进程指定了不同的隔离级别,则会覆盖默认值。通常情况下,如果需要,在触发器本身中可以覆盖默认隔离级别。

根据MSDN页面的DML Triggers

触发器和触发它的语句被视为单个事务,可以从触发器内部回滚。如果检测到严重错误(例如,磁盘空间不足),整个事务将自动回滚。

作用域
提供的上下文是:

{来自你}

两个用户,执行更新到同一个表--甚至是相同的行

{来自问题中第一个链接的MSDN文章,这篇文章“基本上是我正在尝试找到答案的同一个问题”}

插入和删除的表是否作用域限制于当前会话?换句话说,它们只包含当前范围内插入和删除的记录,还是它们包含同一表的所有当前更新操作的记录?甚至能够真正并发执行操作吗,或者锁定将防止此类操作?

在进入inserteddeleted表之前,应该非常清楚,在任何给定时刻,特定行上只会发生单个DML操作。两个或多个请求可能在完全相同的纳秒内到达,但所有请求都会轮流进行,一个接一个(是的,由于锁定)。

关于inserteddeleted表中的内容:是的,只有该特定事件的行才会在这两个伪表中(甚至可以)。如果执行将修改5行的UPDATE操作,则只有这5行会出现在inserteddeleted表中。而且,由于您正在寻找文档,MSDN页面使用inserted和deleted表指出:

deleted表存储DELETE和UPDATE语句期间受影响的行的副本。在执行DELETE或UPDATE语句期间,从触发器表中删除行并将其转移到deleted表中。deleted表和触发器表通常没有共同的行。

inserted表存储INSERT和UPDATE语句期间受影响的行的副本。在插入或更新事务期间,新行被添加到inserted表和触发器表中。inserted表中的行是触发器表中新行的副本。

将此与问题的其他部分联系起来,即涉及到Transaction Isolation Level的部分:Transaction Isolation Level对inserteddeleted表没有任何影响,因为它们专门针对该事件/查询。但是,该操作的净影响(在这两个伪表中捕获)仍然可以在其他进程使用READ UNCOMMITTED隔离级别或NOLOCK表提示时看到。为了澄清一些事情,上面链接的MSDN页面关于 inserted 和 deleted 表在开头就声明它们是“内存中”的,但这并不完全正确。从SQL Server 2005开始,这两个伪表实际上基于 tempdb 。 MSDN页面针对tempdb数据库指出:

 

tempdb 系统数据库是一种全局资源,可供连接到SQL Server实例的所有用户使用,并用于保存以下内容:

 
     
  • ...  

  • 由数据修改事务生成的行版本,用于功能,例如:在线索引操作,多活动结果集(MARS)和AFTER触发器。

     

    在SQL Server 2005之前, inserted 和 deleted 表是从事务日志中读取的(我认为)。


    总之, inserted 和 deleted 表:

       
    • 在Transaction中操作  
    • 是静态的(即只读)表  
    • 仅对当前Trigger可见  
    • 仅包含触发该Trigger实例的特定事件/操作/查询的行

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