Links relacionados Como usar SELECT WITH NOLOCK para melhorar a Performance? Qual a sintaxe correta: NOLOCK ou WITH (NOLOCK)? NOLOCK e INSERT/UPDATE/DELETE Problemas com NOLOCK Efeitos colaterais do NOLOCK – Parte 1 Efeitos colaterais do NOLOCK – Parte 2
Links relacionados
O comando NOLOCK avisa o processador do SQL Server para evitar a utilização de bloqueios (LOCK) durante a leitura de dados. Porém, o SQL Server continua utilizando os bloqueios durante operações de modificação de dados e não há como mudar esse comportamento. A utilização do NOLOCK é, portanto, inválida para as tabelas que terão registros afetados por INSERT, DELETE e UPDATE.
INSERT tbUsuarios WITH (NOLOCK) (nome) VALUES ('A')
DELETE tbUsuarios WITH (NOLOCK) WHERE id = 1
UPDATE tbUsuarios WITH (NOLOCK) SET nome = 'B' WHERE id = 1
Esses comandos resultam no erro:
Msg 1065, Level 15, State 1, Line 15 The NOLOCK and READUNCOMMITTED lock hints are not allowed for target tables of INSERT, UPDATE, DELETE or MERGE statements.
Msg 1065, Level 15, State 1, Line 15
The NOLOCK and READUNCOMMITTED lock hints are not allowed for target tables of INSERT, UPDATE, DELETE or MERGE statements.
A restrição do NOLOCK se aplica somente à tabela que receberá os novos registros, sendo ainda possível utilizar NOLOCK para as tabelas que fornecem os registros. Exemplo:
INSERT tbHistorico (Nome) SELECT Nome FROM tbUsuarios WITH (NOLOCK)
A sintaxe do comando DELETE permite utilizar o NOLOCK para as tabelas que não terão registros apagados. Por exemplo, em uma operação de JOIN entre tabelas, aquelas usadas para leitura aceitam o NOLOCK.
-- FUNCIONA DELETE tbHistorico FROM tbUsuarios u WITH (NOLOCK) WHERE tbHistorico.id=u.id
-- FUNCIONA
Nesse caso, a restrição se aplica somente a tbHistorico. A tabela tbUsuarios é utilizada somente para leitura e permite a utilização de NOLOCK.
A mesma regra se aplica ao UPDATE. Em uma operação de JOIN, as tabelas usadas para leitura aceitam o NOLOCK ea restrição se aplica somente a tabela que será modificada.
-- FUNCIONA UPDATE tbHistorico SET Nome = u.Nome FROM tbUsuarios u WITH (NOLOCK) WHERE tbHistorico.id=u.id