Eu estava lendo a resposta daqui (de stackoverflow, acho que deveria perguntar aqui)
NOLOCK significa não colocar nenhum cadeado.
Sua consulta pode retornar partes de dados antes de UPDATE e partes posteriores a UPDATE em uma única consulta.
Entendo que o nolock não colocará o bloqueio na tabela, para que outras pessoas possam consultar ao mesmo tempo.
A partir da resposta e do exemplo mostrado, ele busca dados enquanto os dados estão sendo atualizados.
Por que isso acontece?
Estou assumindo que, para a seleção normal, ele tentará colocar o bloqueio na tabela; portanto, quando a instrução de atualização for executada, ele colocará um bloqueio na linha ou na página. Então, quando tento executar a instrução select, ela não pode colocar o bloqueio até que o bloqueio da instrução de atualização seja liberado.
Mas neste caso porque a instrução select não tenta colocar lock na tabela, então ela pode rodar sem esperar que a instrução update libere o lock?
Não é bem verdade que isso
NOLOCK
significa não colocar fechaduras. As consultas sob esta dica ainda terãoSch-S
bloqueios e ( possivelmenteHOBT
bloqueios).No
read committed
nível de isolamento, o SQL Server ( normalmente ) obterá bloqueios de nível de linhaS
e os liberará assim que os dados forem lidos. Eles são incompatíveis com osX
bloqueios mantidos em atualizações não confirmadas e, portanto, evitam leituras sujas.No exemplo da resposta vinculada, a
SELECT
consulta não é bloqueada quando encontra uma linha modificada, portanto, é bastante provável que a leitura de atualizações parciais.Também pode acontecer no
read committed
nível de isolamento padrão, embora umSELECT
leia algumas linhas com o valor "antes" e outras com o valor "depois". Só é necessário criar uma situação em queR1
e libera seuS
bloqueioR2
e leva umX
bloqueioR2
e é bloqueada.R1
e leva umX
bloqueio.R2
Esse tipo de situação pode surgir, por exemplo, se o
SELECT
eUPDATE
estiver usando índices diferentes para localizar as linhas de interesse.Exemplo
Agora, em uma janela de consulta, execute
Isso será executado em um loop infinito. Em outra corrida
Isso provavelmente interromperá o loop na outra consulta (tente novamente, caso contrário), o que significa que deve ter lido
A,AA
ouAA,A
A dica
NOLOCK
equivale ao nível de isolamento da transaçãoREAD UNCOMMITTED
, apenas restrita ao escopo de um método de acesso à tabela.Qual RU faz com que o não confirmado apareça no seu conjunto de resultados? Hmm, na verdade é uma questão de " o que não faz . Vou explicar abaixo.
Bem (isso é uma simplificação grosseira, eu sei) MSSQL (em seu comportamento padrão) é um mecanismo de bloqueio - o que significa que ele usa bloqueio para ler/gravar dados de maneira consistente. Nesta explicação simplificada, o MSSQL usa dois tipos de bloqueios: bloqueio compartilhado e bloqueio exclusivo .
Um bloqueio compartilhado (S) é um bloqueio que permite que um recurso (que pode ser uma linha, página de linhas ou até mesmo uma tabela inteira) seja lido - mas não permite uma gravação nele. Portanto, se a transação T1 colocar um bloqueio S na linha R1, todas as transações que tentarem ler R1 obterão essa leitura, mas enquanto o bloqueio S estiver ativo, ninguém poderá gravar em R1.
Um bloqueio exclusivo(X) é a contrapartida do bloqueio compartilhado. Ele permite acesso exclusivo a um recurso - nenhuma outra transação pode ler ou escrever, exceto aquela que obteve o bloqueio X. No exemplo acima, se T1 obteve não um bloqueio S, mas um bloqueio X em R1, ninguém, exceto T1, pode lê-lo ou escrevê-lo.
Essa é a teoria. Os níveis de isolamento respeitam as fechaduras, respeitando a sua prevalência e características. Todos, exceto
READ UNCOMMITTED
. É simples dar um * (coloque aqui seu palavrão de sua preferência) para os bloqueios referentes à leitura - você ainda não pode atualizar a linha outra transação obteve um bloqueio X. Ele simplesmente diz: "Vou ler tudo o que é relevante para o plano de consulta - desconsidere quais bloqueios estão nele." E faça isso.