UPDATE 或 DELETE 语句的非目标表上是否忽略了WITH (NOLOCK) 提示?

Par*_*dox 3 sql-server t-sql

在 SQL Server 数据库中,UPDATE 和 DELETE 语句中的目标表上的WITH (NOLOCK) 查询提示将被忽略。但是,这是否也适用于更新或删除连接中包含的表?例如,是:

update t
set value1 = 123
FROM mytable t
inner join othertable o with (nolock) on t.id = o.id
Run Code Online (Sandbox Code Playgroud)

相当于:

update t
set value1 = 123
FROM mytable t
inner join othertable o on t.id = o.id
Run Code Online (Sandbox Code Playgroud)

Mar*_*ith 6

不,它没有被忽略。这很容易测试。

设置

DROP TABLE IF EXISTS mytable, othertable

CREATE TABLE mytable(id INT, value1 INT)
CREATE TABLE othertable(id INT, dirtyvalue INT)

INSERT mytable VALUES (1, NULL)
INSERT othertable  VALUES (1, 100)
Run Code Online (Sandbox Code Playgroud)

连接1

BEGIN TRAN

UPDATE othertable SET dirtyvalue = 999

WAITFOR DELAY '00:02:00' /*To give time to run connection 2*/

ROLLBACK
Run Code Online (Sandbox Code Playgroud)

连接 2(虽然上面仍在运行)

update t
set value1 = o.dirtyvalue
output inserted.value1
FROM mytable t
inner join othertable o  with (nolock) on t.id = o.id
Run Code Online (Sandbox Code Playgroud)

未提交的999值用于更新,而不是像100在 RCSI 上运行时没有提示的情况那样,或者在 RC 锁定隔离级别上运行时被阻止。

请注意,该999值从未实际提交,othertable因此此处的使用NOLOCK意味着持续存在的状态在mytable逻辑上从未存在过。