Eu estava investigando alguns bloqueios quando vi uma consulta parecida com esta:
SELECT SomeField FROM SomeTable NOLOCK
Eu vi o NOLOCK
e fiquei curioso como ele poderia estar bloqueando outras consultas, neste caso DELETE
declarações. Dei uma olhada rápida nas fechaduras usando sp_lock
e aqui está o que vi:
DB S GRANT
TAB IS GRANT
PAG S GRANT
Agora, meu entendimento é que NOLOCK
deveria ter apenas um bloqueio de estabilidade de esquema, por que foi então pegando um bloqueio IS?
Minha curiosidade foi aguçada. Eu olhei no BOL e vi que havia duas maneiras de usá-lo, WITH (NOLOCK)
e o obsoleto (NOLOCK)
, então decidi experimentá-los. Eu executei as seguintes consultas seguidas pela execução sp_lock
:
SELECT SomeField FROM SomeTable WITH (NOLOCK)
CONCESSÃO DB S CONCESSÃO TAB Sch-S
SELECT SomeField FROM SomeTable (NOLOCK)
CONCESSÃO DB S CONCESSÃO TAB Sch-S
Com certeza, existem meus bloqueios de estabilidade de esquema. Então, minha pergunta é esta: o que está acontecendo aqui? Se a sintaxe aceita para usar NOLOCK for WITH (NOLOCK)
ou (NOLOCK)
, por que a consulta não apresenta um erro quando é executada simplesmente NOLOCK
(sem os parênteses)? Se for suportado, por que está agarrando um bloqueio IS? O que estou perdendo aqui? Estive pesquisando online por uma resposta, mas até agora não consegui.
Eu testei isso em 2008R2 e 2012.
significa que você acabou de criar um alias
SomeTable AS NOLOCK
. Tente o abaixo para ver isso claramente:Isso obviamente não tem efeito sobre o comportamento de bloqueio da consulta. A consulta não falha porque, apesar de ser uma palavra-chave e mostrar azul no SSMS, NOLOCK não é uma palavra reservada no Transact-SQL e, portanto, não causa erro de sintaxe. Lista de palavras reservadas: https://msdn.microsoft.com/en-us/library/ms189822.aspx
Sintaxe correta para usar como dica:
(NOLOCK)
é válido, mas obsoleto.WITH (NOLOCK)
é a sintaxe recomendada.