了解NOLOCK提示

时间:2014-04-25 08:07:53

标签: sql sql-server transaction-isolation nolock

假设我有一个包含1,000,000行的表,并且在此表上运行SELECT * FROM TableName大约需要10秒钟才能返回数据。

如果没有一个NOLOCK语句(一方讨论脏读),这个查询会锁定表10秒,这意味着没有其他进程可以读取或写入表吗?

我经常被DBA告知,然后在查询实时数据以诊断数据问题时,我应该使用NOLOCK来确保我不会锁定表格,这可能会给用户带来问题。这是真的吗?

3 个答案:

答案 0 :(得分:2)

NOLOCK表提示将导致不会对相关表采取共享锁;与READUNCOMMITTED隔离级别相同,但这次不适用于单个表,而是适用于所涉及的所有内容。所以,答案是“不,它不会锁定表格”。请注意,即使使用readuncommitted,仍然可以保留可能的模式锁。

不要求共享锁定读取操作可能会读取脏数据(已更新但尚未提交)和不存在的数据(已更新但已回滚),在任何情况下都会在事务上不一致,并且甚至会跳过整个页面好(如果页面拆分与读取操作同时发生)。

指定NOLOCKREADUNCOMMITTED不被视为良好做法。当然会更快。只要确保你了解后果。

此外,根据文档,将在未来版本中删除对UPDATE和DELETE语句中这些提示的支持。

答案 1 :(得分:1)

当您要求所有数据时,您的查询将尝试获取表级锁定。所以是的,它将在查询期间保持,并且所有其他进程尝试获取该表上的Exclusive锁,并将其置于等待队列中。也试图从该表中读取的进程不会被阻止。

在实时系统上执行的任何诊断都应谨慎进行,使用NOLOCK提示将允许您查看数据而不会对用户造成任何争用。

编辑:正如所指出的,更新锁与共享锁兼容。所以不会被读取过程阻止。

答案 2 :(得分:1)

即使使用NOLOCK,SQL Server也可以选择覆盖并获取锁定。由于某种原因,它被称为QUERY **HINT**。避免锁定的确定方法是在会话开始时使用SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED