Boa tarde pessoal, como eu disse antes queria fazer o último post técnico do ano, talvez ainda não seja esse o último temos mais alguns dias pela frente rs.
Bom essa vai ser uma dica rápida e bem interessante, bom a maioria de vocês já deve conhecer e bem o tão criticado e muito utilizado hint de tabela ‘Nolock’, em palavras resumidas ele não emiti locks para leitura e não fica bloqueado por operações de Updates podendo fazer o que chamamos de leitura ‘suja’ que é equivalente ao nível de isolamento READUNCOMMITTED.
Sabemos que em diversos casos o ‘Nolock’ pode nos ajudar bastante, já prestei serviços em ambientes que o uso do ‘Nolock’ é obrigatório, vamos ver um exemplo sobre seu uso.
Para o exemplo vou utilizar um banco de dados meu já existente.
Esse é o uso tradicional do Hint ‘Nolock’, especificado pela cláusula WITH.
— Na primeira sessão abra a transação de UPDATE begin tran update TB_JOGADORES set NOME = ‘teste’ where APELIDO = ‘rafa’ –Na segunda sessão execute o SELECT SELECT * FROM TB_JOGADORES With(nolock) where APELIDO = ‘rafa’
Porém sabemos que o nosso amigo ‘NOLOCK’ funciona também sem a cláusula ‘WITH’
SELECT * FROM TB_JOGADORES (nolock) where APELIDO = ‘rafa’
Os dois SELECTs acima funcionam e realizam a leitura suja normalmente e retornam a informação rapidamente.
Há algum tempo atrás peguei alguns SELECTs rodando da seguinte forma na empresa que trabalhava.
SELECT * FROM TB_JOGADORES nolock where APELIDO = ‘rafa’
Sem os parênteses () e que em algumas ocasiões eu via o mesmo sendo bloqueado por outra operação de Update, hum algo estranho estava acontecendo ai rs. Bom vamos ver o plano de execução dessa query então.
Aparentemente tudo normal, fazendo uma operação de Scan na tabela ‘TB_JOGADORES’, vamos ver mais detalhes desse operador Clustered Index Scan.
Quando cheguei aqui, o mistério estava resolvido, o Hint ‘Nolock’ sem a cláusula ‘WITH’ e sem os parênteses () não é mas entendido como um Hint pelo otimizador de consultas do SQL Server e o Nolock vira o ‘Apelido’ da tabela e consequentemente esse SELECT vai ficar bloqueado, tanto que você pode fazer esse tipo de consulta.
SELECT * FROM TB_JOGADORES nolock where nolock.APELIDO = ‘rafa’
O otimizador entende que o Nolock é a sua tabela, então se você ver por ai algum caso onde o ‘Nolock’ estiver sem parênteses () de uma olhada no seu plano de execução, provavelmente vai ser mais um caso do ‘Falso Nolock’, prefira sempre utilizar a cláusula ‘WITH (Nolock)’.
Não sei exatamente a versão do SQL Server que mudou isso, eu testei nas versões 2000, 2008 R2, 2012, 2014 e 2016, não sei se um dia isso chegou a funcionar. Futuramente o ‘(Nolock)’ sem a cláusula ‘WITH’ será descontinuada também.
Bom é isso galera, até a próxima dica.
Dica de leitura:
Reginaldo Silva