Я исследовал некоторые блокировки, когда увидел запрос, который выглядел примерно так:
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.
источник
SELECT SomeField FROM SomeTable NOLOCK (NOLOCK)
для двойного эффекта nolock;)Ответы:
означает, что вы только что псевдоним
SomeTable AS NOLOCK
. Попробуйте ниже, чтобы увидеть это ясно:Это, очевидно, не влияет на поведение блокировки запроса. Запрос не терпит неудачу, потому что несмотря на то, что он является ключевым словом и отображается синим цветом в SSMS, NOLOCK не является зарезервированным словом в Transact-SQL и, следовательно, не вызывает синтаксической ошибки. Список зарезервированных слов: https://msdn.microsoft.com/en-us/library/ms189822.aspx
Правильный синтаксис для использования в качестве подсказки:
(NOLOCK)
действителен, но не рекомендуется.WITH (NOLOCK)
это рекомендуемый синтаксис.источник