好吧,隔离级别和范围是两个非常不同的东西。
隔离级别
触发器在事务中运行。默认情况下,该事务应使用默认隔离级别READ COMMITTED。但是,如果调用进程指定了不同的隔离级别,那么它将覆盖默认值。像往常一样:如果需要,您应该能够在触发器本身内覆盖它。
根据DML Triggers的MSDN页面:
触发器和触发它的语句被视为单个事务,可以从触发器内回滚。如果检测到严重错误(例如磁盘空间不足),整个事务会自动回滚。
范围
提供的上下文是:
{来自你}
两个用户,对同一个表执行更新——甚至是相同的行
{来自问题中第一篇链接的 MSDN 文章,即“我试图找到的答案基本上是同一个问题”}
插入和删除的表是否限定在当前会话范围内?换句话说,它们将只包含当前范围的插入和删除记录,还是包含针对同一个表的所有当前更新操作的记录?甚至可以有真正的并发操作吗?或者锁会阻止这种情况发生吗?
在进入inserted 和deleted 表之前,应该非常清楚的是,在任何给定时刻,特定行上只会发生一个 DML 操作。两个或多个请求可能会在完全相同的纳秒内进入,但所有请求都会轮流进行,一次一个(是的,由于锁定)。
现在,关于inserted 和deleted 表中的内容:是的,只有该特定事件的行将(甚至可以)在这两个伪表中。如果您执行将修改 5 行的 UPDATE,则只有这 5 行将在 inserted 和 deleted 表中。由于您正在寻找文档,Use the inserted and deleted Tables 的 MSDN 页面指出:
deleted 表在 DELETE 和 UPDATE 语句期间存储受影响行的副本。在执行 DELETE 或 UPDATE 语句期间,行会从触发器表中删除并转移到已删除的表中。删除的表和触发器表通常没有共同的行。
插入的表在 INSERT 和 UPDATE 语句期间存储受影响行的副本。在插入或更新事务期间,新行会同时添加到插入的表和触发器表中。插入表中的行是触发器表中新行的副本。
回到问题的另一部分,即与事务隔离级别相关的部分:事务隔离级别对inserted 和deleted 表绝对没有影响,因为它们专门与该事件/查询相关.但是,如果其他进程使用READ UNCOMMITTED 隔离级别或NOLOCK 表提示,则在这两个伪表中捕获的该操作的净效果仍然可以可见 .
为了澄清一点,上面链接的关于inserted 和deleted 表的MSDN 页面一开始就声明它们“在内存中”,但这并不完全正确。从 SQL Server 2005 开始,这两个伪表实际上基于 tempdb。 tempdb Database 的 MSDN 页面声明:
tempdb 系统数据库是一个全局资源,可供连接到 SQL Server 实例的所有用户使用,用于保存以下内容:
在 SQL Server 2005 之前,inserted 和 deleted 表是从事务日志中读取的(我相信)。
总而言之,inserted 和 deleted 表:
- 在事务中操作
- 是静态(即只读)表
- 仅对当前触发器可见
- 仅包含触发该触发器实例的特定事件/操作/查询的行