Alguém pode explicar as implicações do uso with (nolock)
em consultas, quando você deve / não deve usá-lo?
Por exemplo, se você tiver um aplicativo bancário com altas taxas de transação e muitos dados em determinadas tabelas, em que tipos de consultas o nolock seria bom? Existem casos em que você sempre deve usá-lo / nunca usá-lo?
sql-server
nolock
Andy White
fonte
fonte
Respostas:
WITH (NOLOCK) é o equivalente a usar READ UNCOMMITED como um nível de isolamento de transação. Portanto, você corre o risco de ler uma linha não confirmada que é posteriormente revertida, ou seja, dados que nunca chegaram ao banco de dados. Portanto, embora possa impedir que as leituras sejam bloqueadas por outras operações, ela apresenta um risco. Em um aplicativo bancário com altas taxas de transação, provavelmente não será a solução certa para qualquer problema que você esteja tentando resolver com ele IMHO.
fonte
NOLOCK
com a,SELECT
corre o risco de retornar as mesmas linhas mais de uma vez (dados duplicados) se os dados forem inseridos (ou atualizados) na tabela ao fazer uma seleção.A questão é o que é pior:
Para bancos de dados financeiros, os impasses são muito piores que os valores errados. Eu sei que isso soa ao contrário, mas ouça. O exemplo tradicional de transações de banco de dados é atualizar duas linhas, subtraindo de uma e adicionando a outra. Isso esta errado.
Em um banco de dados financeiro, você usa transações comerciais. Isso significa adicionar uma linha a cada conta. É de extrema importância que essas transações sejam concluídas e as linhas sejam gravadas com êxito.
Colocar o saldo da conta temporariamente errado não é grande coisa, é para isso que serve a reconciliação do final do dia. E um cheque especial de uma conta é muito mais provável de ocorrer porque dois caixas eletrônicos estão sendo usados ao mesmo tempo do que por causa de uma leitura não confirmada de um banco de dados.
Dito isto, o SQL Server 2005 corrigiu a maioria dos bugs
NOLOCK
necessários. Portanto, a menos que você esteja usando o SQL Server 2000 ou anterior, não será necessário.Leitura adicional
Versão em nível de linha
fonte
Infelizmente, não se trata apenas de ler dados não confirmados. Em segundo plano, você pode acabar lendo as páginas duas vezes (no caso de uma divisão de página) ou pode perder totalmente as páginas. Portanto, seus resultados podem ficar totalmente distorcidos.
Confira o artigo de Itzik Ben-Gan . Aqui está um trecho:
fonte
O exemplo do livro de texto para uso legítimo da dica nolock é a amostragem de relatórios em um banco de dados OLTP de alta atualização.
Para dar um exemplo tópico. Se um grande banco de rua dos EUA quisesse executar um relatório por hora procurando os primeiros sinais de uma corrida no nível da cidade, uma consulta nolock poderia examinar as tabelas de transações, somando depósitos e retiradas de dinheiro por cidade. Para esse relatório, a pequena porcentagem de erro causada pelas transações de atualização revertida não reduziria o valor do relatório.
fonte
Não sei por que você não está agrupando transações financeiras em transações de banco de dados (como quando você transfere fundos de uma conta para outra - você não confirma um lado da transação por vez - é por isso que existem transações explícitas). Mesmo se o seu código estiver relacionado às transações comerciais como parece, todos os bancos de dados transacionais podem fazer reversões implícitas no caso de erros ou falhas. Eu acho que essa discussão está bem acima da sua cabeça.
Se você estiver com problemas de bloqueio, implemente a versão e limpe seu código.
Nenhum bloqueio não apenas retorna valores errados, mas também devolve registros e duplicações fantasmas.
É um equívoco comum que sempre faça com que as consultas sejam executadas mais rapidamente. Se não houver bloqueios de gravação em uma tabela, isso não fará nenhuma diferença. Se houver bloqueios na tabela, isso poderá agilizar a consulta, mas existe um motivo pelo qual os bloqueios foram inventados.
Para ser justo, aqui estão dois cenários especiais em que uma dica nolock pode fornecer utilidade
1) Banco de dados do servidor sql anterior a 2005 que precisa executar uma consulta longa no banco de dados OLTP ativo, essa pode ser a única maneira
2) Aplicativo mal escrito que bloqueia registros e retorna o controle para a interface do usuário e os leitores são bloqueados indefinidamente. O Nolock pode ser útil aqui se o aplicativo não puder ser corrigido (terceiros etc.) e o banco de dados for anterior a 2005 ou o controle de versão não puder ser ativado.
fonte
NOLOCK
é equivalente aREAD UNCOMMITTED
, no entanto, a Microsoft diz que você não deve usá-lo paraUPDATE
ouDELETE
declarações:http://msdn.microsoft.com/en-us/library/ms187373.aspx
Este artigo se aplica ao SQL Server 2005, portanto, o suporte a
NOLOCK
existe se você estiver usando essa versão. Para garantir a codificação futura (assumindo que você decidiu usar leituras sujas), você pode usar isso nos procedimentos armazenados:SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
fonte
Você pode usá-lo quando está lendo apenas dados e realmente não se importa se está ou não recebendo dados que ainda não foram confirmados.
Pode ser mais rápido em uma operação de leitura, mas não sei dizer em quanto.
Em geral, eu recomendo não usá-lo - a leitura de dados não confirmados pode ser um pouco confusa, na melhor das hipóteses.
fonte
Outro caso em que geralmente está bom é em um banco de dados de relatórios, onde os dados talvez já estejam antigos e as gravações simplesmente não acontecem. Nesse caso, porém, a opção deve ser definida no banco de dados ou no nível da tabela pelo administrador, alterando o nível de isolamento padrão.
No caso geral: você pode usá-lo quando você está muito certo de que não há problema em ler dados antigos. O importante é lembrar que é muito fácil entender errado . Por exemplo, mesmo que esteja tudo bem no momento em que você escrever a consulta, você tem certeza de que algo não será alterado no banco de dados no futuro para tornar essas atualizações mais importantes?
Também vou entender a noção de que provavelmente não é uma boa ideia no aplicativo bancário. Ou aplicativo de inventário. Ou em qualquer lugar que você esteja pensando em transações.
fonte
Resposta simples - sempre que seu SQL não estiver alterando dados, e você tiver uma consulta que possa interferir em outras atividades (via bloqueio).
Vale a pena considerar todas as consultas usadas para relatórios, especialmente se a consulta demorar mais de, por exemplo, 1 segundo.
É especialmente útil se você tiver relatórios do tipo OLAP em execução em um banco de dados OLTP.
A primeira pergunta a ser feita, porém, é "por que estou me preocupando com isso?" Na minha experiência, a falsificação do comportamento de bloqueio padrão geralmente ocorre quando alguém está no modo "tente qualquer coisa" e esse é um caso em que conseqüências inesperadas não são improváveis. Muitas vezes, é um caso de otimização prematura e pode ser facilmente incorporado em um aplicativo "apenas por precaução". É importante entender por que você está fazendo isso, qual problema ele resolve e se você realmente tem o problema.
fonte
Resposta curta:
Use apenas
WITH (NOLOCK)
na instrução SELECT em tabelas que possuem um índice em cluster.Resposta longa:
WITH (NOLOCK) é frequentemente explorado como uma maneira mágica de acelerar leituras de banco de dados.
O conjunto de resultados pode conter linhas que ainda não foram confirmadas, que geralmente são revertidas posteriormente.
Se WITH (NOLOCK) for aplicado a uma tabela que possui um índice não clusterizado, os índices de linha poderão ser alterados por outras transações, à medida que os dados da linha estiverem sendo transmitidos para a tabela de resultados. Isso significa que o conjunto de resultados pode estar faltando linhas ou exibir a mesma linha várias vezes.
READ COMMITTED adiciona um problema adicional em que os dados são corrompidos em uma única coluna em que vários usuários alteram a mesma célula simultaneamente.
fonte
READ UNCOMITTED
não o afetará. Há uma razão pela qual foi incluída no padrão ANSI.Meus 2 centavos - faz sentido usar
WITH (NOLOCK
) quando você precisa gerar relatórios. Nesse ponto, os dados não mudariam muito e você não gostaria de bloquear esses registros.fonte
Se você estiver lidando com transações financeiras, nunca desejará usá-lo
nolock
.nolock
é melhor usado para selecionar tabelas grandes com muitas atualizações e você não se importa se o registro obtido pode estar desatualizado.Os registros financeiros (e quase todos os outros registros na maioria dos aplicativos)
nolock
causariam estragos, pois você poderia ler os dados de um registro que estava sendo gravado e não obter os dados corretos.fonte
Eu costumava recuperar um "próximo lote" para o que fazer. Nesse caso, não importa qual item exato, e eu tenho muitos usuários executando essa mesma consulta.
fonte
Use nolock quando estiver de acordo com os dados "sujos". O que significa que o nolock também pode ler dados que estão em processo de modificação e / ou dados não confirmados.
Geralmente, não é uma boa ideia usá-lo em ambientes de alta transação e é por isso que não é uma opção padrão na consulta.
fonte
Eu uso com a dica (nolock) particularmente nos bancos de dados SQLServer 2000 com alta atividade. Não tenho certeza de que seja necessário no SQL Server 2005. Recentemente, eu adicionei essa dica no SQL Server 2000 a pedido do DBA do cliente, porque ele estava percebendo muitos bloqueios de registros SPID.
Tudo o que posso dizer é que o uso da dica NÃO nos machucou e parece ter feito o problema de travamento se resolver. O DBA naquele cliente em particular basicamente insistiu em usar a dica.
A propósito, os bancos de dados com os quais lido são back-end para sistemas de reclamações médicas corporativas, por isso estamos falando de milhões de registros e mais de 20 tabelas em muitas associações. Normalmente, adiciono uma dica WITH (nolock) para cada tabela na junção (a menos que seja uma tabela derivada; nesse caso, você não pode usar essa dica específica)
fonte
A resposta mais simples é uma pergunta simples - você precisa que seus resultados sejam repetíveis? Se sim, o NOLOCKS não é apropriado em nenhuma circunstância
Se você não precisar de repetibilidade, os nolocks poderão ser úteis, especialmente se você não tiver controle sobre todos os processos que se conectam ao banco de dados de destino.
fonte