一尘不染

UPDATE + WITH(ROWLOCK)+ CTE

sql

我找不到有关T-SQL语句语法的任何文档:我需要对WITH (ROWLOCK)CTE结果进行UPDATE。

诸如此类:(因此更新将是top1000 table1.col2。WITH (ROWLOCK)在UPDATE期间对table1的行中的语句至关重要)

    ;WITH CTE AS 
    ( 
        SELECT TOP(1000) table1.col2
        FROM  table1 INNER JOIN table2 ON table1.id = table2.id    
    ) 
    UPDATE CTE WITH (ROWLOCK)
    SET col2 = 1

上面的陈述在语法上可能是正确的,但是如果有人可以找到这样的例子,请给我一个链接。

但是:我的完整SQL如下所示。在执行过程中出现错误:

为表“ table1”指定了冲突的锁定提示。这可能是由为视图指定的提示冲突引起的。

为什么我不能WITH (NOLOCK)用于选择和WITH (ROWLOCK)更新?

;WITH CTE AS 
( 
    SELECT TOP(5) table1.col2
    FROM table1 WITH (NOLOCK) INNER JOIN table2 WITH (NOLOCK) ON table1.id = table2.id 
    WHERE table1.col3 = 2
    ORDER BY table1.id    
) 
UPDATE CTE WITH (ROWLOCK)
SET col2 = 1

阅读 146

收藏
2021-05-30

共1个答案

一尘不染

NOLOCK不适用于查询中要修改表的部分。在SQL
Server更新语句中,在对每行进行测试时,请对其进行短暂锁定。这是避免死锁的机制。它可以防止对每行S锁进行多次更新以进行读取,然后尝试对其进行X锁。

您无法使U形锁自动消失。但是,您可以通过自连接将U锁定的行数减少到最小化:

update t1
set ...
from T t1 with (rowlock)
where t1.ID in (select TOP 5 ID from T t2 with (nolock) where ... order by ...)

这增加了一些开销,但允许您NOLOCK进行阅读。

考虑对读取使用快照隔离。NOLOCK有某些问题,例如查询随机中止。

2021-05-30