(NOLOCK) против NOLOCK


24

Я исследовал некоторые блокировки, когда увидел запрос, который выглядел примерно так:

SELECT SomeField FROM SomeTable NOLOCK

Я видел NOLOCKи мне было любопытно, как это может блокировать другие запросы, в данном случае DELETEзаявления. Я быстро взглянул на использование замков sp_lockи вот что я увидел:

DB      S   GRANT

TAB     IS  GRANT

PAG    S    GRANT

Теперь я понимаю, что NOLOCKпредполагается захватить только блокировку стабильности схемы, почему тогда он захватывал блокировку 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

Конечно же, есть мои блокировки схемы устойчивости. Итак, мой вопрос заключается в следующем: что здесь происходит? Если принятый синтаксис для использования NOLOCK - либо, WITH (NOLOCK)либо (NOLOCK), то почему запрос не выдаст ошибку, если он выполняется просто NOLOCK(без скобок)? Если это поддерживается, зачем захватывать блокировку IS? Что мне здесь не хватает? Я искал в Интернете ответ, но пока что не дотянул.

Я проверил это на 2008R2 и 2012.


4
SELECT SomeField FROM SomeTable NOLOCK (NOLOCK)для двойного эффекта nolock;)
— ypercubeᵀᴹ

Ответы:


52
SELECT SomeField
FROM   SomeTable NOLOCK 

означает, что вы только что псевдоним SomeTable AS NOLOCK. Попробуйте ниже, чтобы увидеть это ясно:

SELECT NOLOCK.SomeField
FROM   SomeTable NOLOCK 

Это, очевидно, не влияет на поведение блокировки запроса. Запрос не терпит неудачу, потому что несмотря на то, что он является ключевым словом и отображается синим цветом в SSMS, NOLOCK не является зарезервированным словом в Transact-SQL и, следовательно, не вызывает синтаксической ошибки. Список зарезервированных слов: https://msdn.microsoft.com/en-us/library/ms189822.aspx

Правильный синтаксис для использования в качестве подсказки:

  • (NOLOCK) действителен, но не рекомендуется.
  • WITH (NOLOCK) это рекомендуемый синтаксис.

14
Вау, не уверен, как я этого не понял. Это действительно сводило меня с ума, теперь я просто чувствую смущение :) Иногда это самые простые вещи, я думаю.
— Брайан

2
@ Брайан Не беспокойтесь, недавно мне пришлось отлаживать что-то очень похожее, иначе это было бы не так легко обнаружить! Вы можете понять, почему MS не поддерживает этот синтаксис.
— Гарет Лайонс

NOLOCK не является зарезервированным ключевым словом? Разве это не должно жаловаться, если вы не используете [NOLOCK]?
— Ааронин

6
Нет msdn.microsoft.com/en-us/library/ms189822.aspx Хотя в SSMS он отображается синим цветом, это может вас отбросить.
— Гарет Лайонс

Хороший улов, LOL. Мой любимый Q / A сегодня.
— RBarryYoung
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.