Pergunta

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ê tem uma aplicação bancária com altas taxas de transação e uma grande quantidade de dados em algumas tabelas, nos quais os tipos de consultas que nolock ficar bem? Há casos em que você deve sempre usá-lo / nunca usá-lo?

Foi útil?

Solução

COM (NOLOCK) é o equivalente de usar LEIA UNCOMMITED como um nível de isolamento da transação. Então, você corre o risco de ler uma linha não confirmadas de que é posteriormente revertida, ou seja, dados que nunca fizeram-lo para o banco de dados. Assim, enquanto ele pode impedir que lê a ser bloqueada por outras operações, ele vem com um risco. Em uma aplicação bancária com altas taxas de transação, ele provavelmente não vai ser a solução certa para qualquer problema que estamos tentando resolver com ele IMHO.

Outras dicas

A questão é o que é pior:

  • um impasse, ou
  • um valor errado?

Para bancos de dados financeiros, impasses são muito piores do que os valores errados. Eu sei que soa para trás, mas me ouça. O exemplo tradicional de transações de banco de dados é atualizar duas linhas, subtraindo um e adicionando para outro. Isso está errado.

Em um banco de dados financeira que você usar transações comerciais. Isso significa que a adição de uma linha para cada conta. É de extrema importância que estas transações completas e as linhas são escritas com sucesso.

Obtendo o saldo da conta temporariamente errado não é um grande negócio, que é o que o final do dia de reconciliação é para. E um descoberto a partir de uma conta é muito mais provável de ocorrer porque duas caixas eletrônicos estão sendo usados ??de uma só vez do que por causa de uma leitura não consolidada a partir de um banco de dados.

Dito isso, SQL Server 2005 fixa a maioria dos bugs que tornaram necessária NOLOCK. Então, se você estiver usando o SQL Server 2000 ou anterior, você não deve precisar.

Leitura adicional
linha-nível Versioning

O exemplo do livro de texto para o uso legítimo da dica NOLOCK é relatório de amostragem contra um banco de dados OLTP atualização alta.

Para dar um exemplo tópica. Se um grande US banco de rua queria correr um relatório por hora procurando os primeiros sinais de um nível da cidade executados no banco, uma consulta nolock poderia fazer a varredura tabelas de transação totalizando depósitos em numerário e saques em dinheiro por cidade. Para tal relatório uma minúscula porcentagem de erro causado por transações de atualização para trás rolada não reduziria o valor do relatório.

Infelizmente não é apenas sobre a leitura de dados não confirmados. No fundo você pode acabar lendo páginas duas vezes (no caso de uma divisão da página), ou você pode perder as páginas completamente. Assim, seus resultados podem ser grosseiramente distorcido.

Confira artigo Itzik Ben-Gan . Aqui está um trecho:

" Com a dica NOLOCK (ou definir o nível de isolamento da sessão para ler UNCOMMITTED) você diga SQL Server que você não espera consistência, então não há garantias. Tenha em mente que "os dados inconsistentes" não só significa que você pode ver não confirmadas alterações que foram posteriormente revertidas, ou dados muda em um intermediário estado da transação. Também significa que em uma consulta simples que verifica todos os dados SQL mesa / index Servidor pode perder a posição de varredura, ou você pode acabar recebendo a mesma linha duas vezes . "

Não sei por que você não está envolvendo transações financeiras em operações de banco de dados (como quando você transferir fundos de uma conta para outra - você não cometer um lado da operação em-um-tempo - é por isso que existem transações explícitas) . Mesmo que o seu código é Braindead para transações comerciais, uma vez que soa como ele é, todos os bancos de dados transacionais têm o potencial para fazer reversões implícitas em caso de erros ou fracasso. Acho que esta discussão é muito acima da sua cabeça.

Se você está tendo problemas de bloqueio, implementar o controle de versão e limpar seu código.

No bloqueio não só retorna valores errados ele retorna registros fantasmas e duplicatas.

É um equívoco comum que ele sempre faz consultas correr mais rápido. Se não houver bloqueios de escrita sobre uma mesa, não faz qualquer diferença. Se houver bloqueios na tabela, ele pode fazer a consulta mais rápida, mas há uma razão fechaduras foram inventados em primeiro lugar.

Para ser justo, aqui estão dois cenários especiais, onde uma dica nolock podem fornecer utilidade

1) de banco de dados SQL Server pré-2005, que precisa ser executado longa consulta em banco de dados OLTP ao vivo esta pode ser a única maneira

2) aplicação mal escrita que bloqueia registros e retorna o controle para a interface do usuário e os leitores são indefinidamente bloqueado. Nolock pode ser útil aqui se a aplicação não pode ser fixo (terceiros etc) e banco de dados é ou pré-2005 ou de versões não pode ser ligado.

NOLOCK é equivalente a READ UNCOMMITTED, no entanto Microsoft diz que você não deve usá-lo para UPDATE ou DELETE declarações:

Para atualizar ou excluir declarações: Este recurso será removido em uma versão futura do Microsoft SQL Server. Evite usar esse recurso em novos trabalhos de desenvolvimento e planeje modificar os aplicativos que atualmente usam esse recurso.

http://msdn.microsoft.com/en-us/library/ ms187373.aspx

Este artigo se aplica ao SQL Server 2005, de modo que o suporte para NOLOCK existe se você estiver usando essa versão. A fim de prova de futuro que você código (assumindo que você decidiu uso sujo lê) você poderia usar isso em seus procedimentos armazenados:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Você pode usá-lo quando você estiver lendo apenas os dados, e você realmente não me importo sobre se ou não você pode estar recebendo dados retrospectivos que ainda não está comprometido.

Pode ser mais rápido em uma operação de leitura, mas eu realmente não posso dizer por quanto.

Em geral, eu recomendo contra a usá-lo -. Ler dados não confirmados pode ser um pouco confuso no melhor

Outro caso em que é geralmente bem está em um banco de dados de relatórios, onde os dados é, talvez, já idoso e escreve simplesmente não acontecem. Neste caso, porém, a opção deve ser definida no nível de banco de dados ou tabela pelo administrador alterando o nível de isolamento padrão.

No caso geral: você pode usá-lo quando estiver muito certeza que está tudo bem para ler dados antigos. A coisa importante a lembrar é que a sua muito fácil de obter que errado . Por exemplo, mesmo se está tudo bem no momento em que escrever a consulta, tem certeza de que algo não vai mudar no banco de dados no futuro para fazer essas atualizações mais importante?

Eu vou também 2 a noção de que é provavelmente não uma boa idéia em banca aplicativo. Ou inventário de aplicações. Ou em qualquer lugar que você está pensando sobre as transações.

A resposta é simples -. Não sempre que o SQL é alterar os dados, e você tem uma consulta que pode interferir com outra atividade (via bloqueio)

Vale a pena considerar para qualquer dúvida utilizados para relatórios, especialmente se a consulta demora mais do que, digamos, 1 segundo.

É especialmente útil se você tiver relatórios OLAP do tipo que você está correndo contra um banco de dados OLTP.

A primeira pergunta a fazer, porém, é "por que estou se preocupar com isso?" Em minha experiência, falsificando o comportamento de bloqueio padrão, muitas vezes ocorre quando alguém está no modo de "tentar qualquer coisa" e este é um caso em que conseqüências inesperadas não são improváveis. Demasiadas vezes é um caso de otimização prematura e pode muito facilmente obter esquerda incorporado em um aplicativo "just in case". É importante entender por que você está fazendo isso, qual o problema que ele resolve, e se você realmente tem o problema.

Meus 2 centavos - faz sentido para uso WITH (NOLOCK) quando você precisa para gerar relatórios. Neste ponto, os dados não iria mudar muito e você não gostaria de bloquear esses registros.

Se você está lidando com operações de financiamento, então você nunca vai querer usar nolock. nolock é melhor usado para selecionar a partir de grandes tabelas que possuem atualizações lotes e você não se importa se o registro você começa poderia estar fora de data.

Para registros financeiros (e quase todos os outros registros na maioria das aplicações) nolock iria causar estragos como você poderia ler potencialmente dados de volta a partir de um registro que foi sendo escrito e não obter os dados corretos.

Eu usei para recuperar um "próximo lote" de coisas para fazer. Não importa, neste caso, qual o item exato, e eu tenho um monte de usuários que executam essa mesma consulta.

Resposta curta:

Nunca uso WITH (NOLOCK).

Resposta longa:

NOLOCK é frequentemente explorado como uma forma mágica para acelerar banco de dados lê, mas eu tento evitar usá-lo sempre que possível.

O conjunto de resultados pode conter linhas que ainda não foram comprometidos, que são muitas vezes mais tarde revertida.

Um erro ou result-set pode ser vazia, seja linhas ausentes ou exibir a mesma linha várias vezes.

Isto é porque outras transações estão se movendo dados ao mesmo tempo que você está lendo.

READ COMMITTED acrescenta um problema adicional onde os dados são corrompidos dentro de uma única coluna onde vários usuários mudar a mesma célula ao mesmo tempo.

Existem outros efeitos colaterais também, o que resultará em sacrificar o aumento da velocidade que você estava esperando para ganhar em primeiro lugar.

Pode-se argumentar que não há problema em usá-lo em lugares onde você pode obter afastado com ele, mas o que é o ponto? Eu não consigo pensar em qualquer situação em que os dados corrompidos é aceitável.

Nunca, jamais usar NOLOCK nunca.

(sempre)

Use nolock quando você está bem com os dados "sujos". O que significa nolock também pode ler os dados que está em vias de ser modificado de dados e / ou não-consolidadas.

De modo geral, não é uma boa idéia para usá-lo em ambiente de alta transação e é por isso que não é uma opção padrão na consulta.

Eu uso com (nolock) dica particularmente no SQLServer 2000 bancos de dados com alta atividade. Não estou certo de que ela é necessária em SQL Server 2005 no entanto. Recentemente acrescentou que toque em um SQL Server 2000, a pedido de DBA do cliente, porque ele estava percebendo um monte de SPID recorde fechaduras.

Tudo o que posso dizer é que usando a dica é não ferir-nos e parece ter feito o problema de travamento resolver em si. O DBA naquele determinado cliente, basicamente, insistiu que usar a dica.

A propósito, os bancos de dados que lidamos são back-ends para sistemas de pedidos médicos empresa, então estamos falando de milhões de registros e mais de 20 mesas em muitos junta. Eu normalmente adicionar uma pitada COM (nolock) para cada tabela na junção (a menos que seja uma tabela derivada, caso em que você não pode usar essa dica particular)

A resposta mais simples é uma pergunta simples - você precisa de seus resultados para ser repetitivo? Se sim, então NOLOCKS não é apropriada sob quaisquer circunstâncias

Se você não precisa de repetibilidade então nolocks pode ser útil, especialmente se você não tem controle sobre todos os processos de conexão ao banco de dados de destino.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top