【问题标题】:SQL Server Trigger Isolation / Scope DocumentationSQL Server 触发器隔离/范围文档
【发布时间】:2015-02-17 14:21:06
【问题描述】:

我一直在寻找关于 SQL Server 中触发器的隔离级别(或并发性或范围......我不知道到底该怎么称呼它)的权威文档。

我发现以下来源表明我认为是正确的(也就是说,两个用户对同一个表执行更新——甚至是相同的行——然后将执行独立和隔离的触发器):

第一个问题本质上与我试图找到答案的问题相同,但给出的答案没有提供任何来源。第二个问题也接近分数,答案是一样的,但同样没有提供任何来源。

有人可以指出可用文档在哪里做出相同的断言吗?

谢谢!

【问题讨论】:

  • 是的。 1 个用户将无法同时查看来自第二个用户的数据。当然,假设触发器没有使用未提交的读取或未锁定。这很容易向自己证明。创建一个带触发器的表。然后在 SSMS 中打开 1 个选项卡并开始事务并执行插入。不要提交该事务并在第二个选项卡中执行相同操作。第二个选项卡看不到选项卡 1 中未提交的数据。
  • 我不确定您是否会找到任何官方文档以您想要的形式明确说明这一点。但很容易想象,如果不是这样,触发器的开发会有多混乱。
  • @Damien_The_Unbeliever 我链接到的一些官方文件给出了一些细节。

标签: sql-server triggers isolation-level


【解决方案1】:

好吧,隔离级别和范围是两个非常不同的东西。

隔离级别
触发器在事务中运行。默认情况下,该事务应使用默认隔离级别READ COMMITTED。但是,如果调用进程指定了不同的隔离级别,那么它将覆盖默认值。像往常一样:如果需要,您应该能够在触发器本身内覆盖它。

根据DML Triggers的MSDN页面:

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

范围
提供的上下文是:

{来自你}

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

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

插入和删除的表是否限定在当前会话范围内?换句话说,它们将只包含当前范围的插入和删除记录,还是包含针对同一个表的所有当前更新操作的记录?甚至可以有真正的并发操作吗?或者锁会阻止这种情况发生吗?

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

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

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

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

回到问题的另一部分,即与事务隔离级别相关的部分:事务隔离级别对inserteddeleted 表绝对没有影响,因为它们专门与该事件/查询相关.但是,如果其他进程使用READ UNCOMMITTED 隔离级别或NOLOCK 表提示,则在这两个伪表中捕获的该操作的净效果仍然可以可见 .

为了澄清一点,上面链接的关于inserteddeleted 表的MSDN 页面一开始就声明它们“在内存中”,但这并不完全正确。从 SQL Server 2005 开始,这两个伪表实际上基于 tempdbtempdb Database 的 MSDN 页面声明:

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

  • ...

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

在 SQL Server 2005 之前,inserteddeleted 表是从事务日志中读取的(我相信)。


总而言之,inserteddeleted 表:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    • 2014-10-12
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    相关资源
    最近更新 更多