UPDATE + WITH(ROWLOCK)+ CTE

时间:2014-11-27 19:09:11

标签: sql sql-server sql-server-2008 tsql sql-server-2012

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

类似于:(如此更新将是top1000 table1.col2。**在表1的行UPDATE期间对语句WITH(ROWLOCK)至关重要**)

    ;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

1 个答案:

答案 0 :(得分:3)

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

你不能让U型锁远离AFAIK。但是你可以通过自联接来减少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存在某些问题,例如查询随机中止。