使用 Nolock 提示更新查询

Posted

技术标签:

【中文标题】使用 Nolock 提示更新查询【英文标题】:Update Query with Nolock hint 【发布时间】:2014-02-18 14:20:41 【问题描述】:

我正在尝试在更新查询中添加 with(NOLOCK):

UPDATE pth_patchLookup with(nolock) SET ScanDateTime = Getdate() WHERE RegID = 312

但我收到以下消息:

NoLock hint is supported only with Select statement and not with update, insert and delete.

有什么方法可以在这个更新查询上应用“NOLOCK”吗?

感谢您的帮助

【问题讨论】:

通常(NOLOCK) 不是您想要的...有些副作用可能会让您感到惊讶。 READ COMMITTED SNAPSHOT ISOLATION 可能会更好地为您提供(可能)想要的东西,但它需要更改数据库。请参阅this post 了解更多信息。 你想达到什么目的? @GarethD 有多个实例更新表时发生死锁(SQL 错误 1205) 没有锁的更新是自相矛盾的。 @GarethD 关于如何完成您所描述的更多限制性锁的任何建议? 【参考方案1】:

(NOLOCK) 禁用共享锁而不是排他锁。 您可以使用 Read Committed 隔离级别来对 select 语句设置排他锁。

SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
UPDATE pth_patchLookup SET ScanDateTime = Getdate() WHERE RegID = 312

【讨论】:

这会得到同样的错误 - NoLock hint is supported only with Select statement and not with update, insert and delete.【参考方案2】:

还有这个?

UPDATE TOP (1000) v 
SET idSupervisor = a.supervisor
FROM    dbo.Venda_2014 v WITH ( NOLOCK )
INNER JOIN #supervidores_presentes a WITH (NOLOCK) ON v.IdVendedor = a.vendedor AND v.idEmpresaOriginal = a.empresa
WHERE   IdDistribuidor IN ( 40 )
        AND ISNULL(v.idSupervisor,0) = 0
        AND datAnoMesRef >= '201501' 
Go

对我来说工作得很好。

【讨论】:

【参考方案3】:

NOLOCK 是一个选择(仅)提示,对于老程序员来说,这是一个坏习惯,因为它在 SQL Server 7 中几乎是强制性的,但从 SQL Server 2000 开始就没有必要了。 该提示特别告诉引擎选择可以读取行,即使它处于未提交事务的中间。因此,您可能会遇到脏读或鬼读。

我强烈建议您阅读隔离级别以了解如何满足您的特定系统要求。

Obs:提示不是命令,您只是建议引擎接受提示,但引擎可以决定不使用它。

【讨论】:

以上是关于使用 Nolock 提示更新查询的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 等效于 SQLServer 的 NoLock 提示

在我的情况下,With(NoLock) 提示是不是危险?

带有 (NOLOCK) 提示的 SQL 服务器

使用 nolock 的 Java Hibernate HQL 查询

NOLOCK(Sql Server 提示)是不好的做法吗?

SQL Server NOLOCK 提示会返回部分写入的行吗?