一位同事写了一个使用提示"with(NOLOCK,NOWAIT)"的查询.
例如
select first_name, last_name, age
from people with (nolock,nowait)
Run Code Online (Sandbox Code Playgroud)
假设:
NOLOCK说"不要担心任何级别的锁定,现在只需读取数据"
NOWAIT说"不要等,如果表被锁定就会出错"
问题:
为什么同时使用两者?当然NOWAIT永远不会实现,因为NOLOCK意味着它不会等待锁定......?
这是多余的(或至少是无效的).在一个查询窗口中,执行:
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确实需要等待一些锁.