为什么一起使用NOLOCK和NOWAIT?

Ric*_*ich 6 t-sql sql-server

一位同事写了一个使用提示"with(NOLOCK,NOWAIT)"的查询.

例如

select first_name, last_name, age
from people with (nolock,nowait)
Run Code Online (Sandbox Code Playgroud)

假设:

NOLOCK说"不要担心任何级别的锁定,现在只需读取数据"

NOWAIT说"不要等,如果表被锁定就会出错"

问题:
为什么同时使用两者?当然NOWAIT永远不会实现,因为NOLOCK意味着它不会等待锁定......?

Dam*_*ver 6

这是多余的(或至少是无效的).在一个查询窗口中,执行:

create table T (ID int not null)
begin transaction
alter table T add ID2 int not null
Run Code Online (Sandbox Code Playgroud)

打开此窗口,打开另一个查询窗口并执行:

select * from T WITH (NOLOCK,NOWAIT)
Run Code Online (Sandbox Code Playgroud)

尽管有NOWAIT提示,尽管它被记录为在遇到任何锁定时立即返回消息,但第二个查询将挂起,等待Schema锁定.

阅读表提示上的文档:

NOWAIT:

一旦在表上遇到锁定,就指示数据库引擎返回消息

请注意,这是关于锁,任何锁.

NOLOCK(实际上READUNCOMMITTED):

READUNCOMMITTED和NOLOCK提示仅适用于数据锁.所有查询(包括具有READUNCOMMITTED和NOLOCK提示的查询)在编译和执行期间都会获取Sch-S(模式稳定性)锁.因此,当并发​​事务在表上持有Sch-M(模式修改)锁时,将阻止查询.

所以,NOLOCK确实需要等待一些锁.