当我看到一个看起来像这样的查询时,我正在调查一些阻塞:
SELECT SomeField FROM SoMetable NOLOCK
我看到了NOLOCK并且好奇它是如何阻止其他查询的,在这种情况下是DELETE语句.我使用sp_lock快速查看了锁,这是我看到的:
DB S GRANT TAB IS GRANT PAG S GRANT
现在,我的理解是NOLOCK应该只采用Schema-Stability锁,为什么它会抓住IS锁?
我的好奇心被激怒了.我查看了BOL并看到有两种方法可以使用它,WITH(NOLOCK)和不推荐使用(NOLOCK),所以我决定尝试一下.我运行了以下查询,然后运行sp_lock:
SELECT SomeField FROM SoMetable WITH (NOLOCK)
DB S GRANT TAB Sch-S GRANT
SELECT SomeField FROM SoMetable (NOLOCK)
DB S GRANT TAB Sch-S GRANT
果然,有我的Schema-Stability锁.所以我的问题是:这里发生了什么?如果使用NOLOCK的语法是WITH(NOLOCK)或(NOLOCK),那么为什么当它只用普通的NOLOCK(没有括号)运行时查询错误?如果支持,为什么要抓住IS锁?我在这里想念的是什么?我一直在网上寻找答案,但到目前为止已经很短了.
我在2008R2和2012都测试了这个.
解决方法
SELECT SomeField FROM SoMetable NOLOCK
意味着你只是将SoMetable别名为NOLOCK.请尝试以下内容清楚地看到:
SELECT NOLOCK.SomeField FROM SoMetable NOLOCK
这显然对查询的锁定行为没有影响.查询不会失败,因为尽管是关键字&在SSMS中显示蓝色,NOLOCK不是Transact-sql中的保留字,因此不会导致语法错误.保留字列表:https://msdn.microsoft.com/en-us/library/ms189822.aspx
正确的语法用作提示:
>(NOLOCK)有效但已弃用.> WITH(NOLOCK)是推荐的语法.