(NOLOCK) VS NOLOCK

Bri*_*ian 24 sql-server syntax nolock

当我看到一个看起来像这样的查询时,我正在调查一些阻塞:

SELECT SomeField FROM SomeTable NOLOCK
Run Code Online (Sandbox Code Playgroud)

我看到了NOLOCK并且很好奇它是如何阻塞其他查询的,在这种情况下是DELETE语句。我快速查看了使用的锁sp_lock,这是我所看到的:

DB      S   GRANT

TAB     IS  GRANT

PAG    S    GRANT
Run Code Online (Sandbox Code Playgroud)

现在,我的理解是NOLOCK应该只需要一个 Schema-Stability 锁,为什么它会抓住一个 IS 锁?

我的好奇心被勾起来了。我查看了 BOL,发现有两种使用方法,WITH (NOLOCK)以及已弃用的 . (NOLOCK),所以我决定尝试一下。我运行了以下查询,然后运行sp_lock

SELECT SomeField FROM SomeTable WITH (NOLOCK)
Run Code Online (Sandbox Code Playgroud)
DB S 赠款

TAB Sch-S 授权
SELECT SomeField FROM SomeTable (NOLOCK)
Run Code Online (Sandbox Code Playgroud)
DB S 赠款

TAB Sch-S 授权

果然,有我的模式稳定性锁。所以我的问题是:这里发生了什么?如果使用 NOLOCK 的公认语法是WITH (NOLOCK)or (NOLOCK),那么为什么查询在只使用普通NOLOCK(不带括号)运行时不会出错?如果支持,为什么要抢 IS 锁?我在这里缺少什么?我一直在网上搜索答案,但到目前为止还不够。

我已经在 2008R2 和 2012 上对此进行了测试。

Gar*_*ons 52

SELECT SomeField
FROM   SomeTable NOLOCK 
Run Code Online (Sandbox Code Playgroud)

意味着你刚刚别名SomeTable AS NOLOCK. 尝试以下操作以清楚地看到这一点:

SELECT NOLOCK.SomeField
FROM   SomeTable NOLOCK 
Run Code Online (Sandbox Code Playgroud)

这显然对查询的锁定行为没有影响。查询不会失败,因为尽管是关键字并在 SSMS 中显示为蓝色,但 NOLOCK 不是Transact-SQL 中的保留字,因此不会导致语法错误。保留字列表:https : //msdn.microsoft.com/en-us/library/ms189822.aspx

用作提示的正确语法:

  • (NOLOCK) 有效但已弃用。
  • WITH (NOLOCK) 是推荐的语法。

  • 哇,不知道我怎么没弄明白。这真的让我发疯,现在我只是觉得很尴尬:) 我想有时候这是最简单的事情。 (14认同)
  • 不,https://msdn.microsoft.com/en-us/library/ms189822.aspx 虽然它在 SSMS 中以蓝色显示,但可能会让您失望。 (6认同)
  • @Brian 不用担心,我最近不得不调试一些非常相似的东西,否则可能不容易发现!您可以看到为什么 MS 已弃用该语法。 (2认同)