Benefícios do NÍVEL DE ISOLAMENTO DA TRANSAÇÃO CONJUNTO LIDO SEM COMPROMISSO

12

Eu uso SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDna maioria das minhas consultas SQL gerais, principalmente porque isso foi aprofundado para mim quando originalmente aprendi o idioma.

Pelo meu entendimento, esse nível de isolamento age da mesma maneira que, WITH (NO LOCK)no entanto, só tenho a tendência de usar SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

  • Existe sempre um tempo que eu deveria estar usando WITH (NO LOCK)mais SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.
  • Impede SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDque outros usuários sejam bloqueados nas tabelas que estou lendo?
  • Se SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDfor usado para interromper bloqueios, mas estou apenas lendo dados, qual é o sentido de usá-los? É apenas consultas intensivas do sistema que gerariam bloqueios? Vale a pena usá-lo ao executar consultas que retornariam em, digamos, 5 a 10 segundos?
  • Foi-me dito para não usar SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDao ler dados que seriam usados ​​em atualizações, presumivelmente para evitar a atualização de dados sujos. Essa seria a única razão?
  • Com o tipo de banco de dados em que estou trabalhando, há um ambiente de produção e teste. Raramente, consultaremos o ambiente de produção, mas, quando necessário, geralmente o utilizarei SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDna minha consulta. Entendo que leituras sujas são possíveis com isso. Além de receber dados de volta que podem não acabar sendo comprometidos com o banco de dados (e, portanto, jogar fora meus resultados), que outros tipos de 'leituras sujas' poderiam ser possíveis?

Desculpe pelas perguntas em massa.

dmoney
fonte
2
Você pode ler os mesmos dados duas vezes é outra queda do poço. Usar RU ou NO LOCK como padrão é uma má ideia.
James Anderson
9
Eu não usaria READ UNCOMMITTEDtoda parte, na exata mesma maneira que eu não iria usar WITH (NOLOCK)em todos os lugares (que são essencialmente a mesma coisa) blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere
Mark Sinkinson
1
Examine os modelos de isolamento SNAPSHOT. Eles são muito mais fortes que o RCU e também não bloqueiam ou causam bloqueio. Eles parecem um bom modelo padrão para você (em vez de usar o RCU!).
usr

Respostas:

25

É terrível que você tenha aprendido dessa maneira (desculpe!).

READ UNCOMMITTEDvamos ler todas as linhas, sim. Mesmo aqueles que são usados atualmente em uma INSERT, UPDATE, DELETEoperação. Isso é muito útil se você precisar dar uma olhada rápida em alguns Dados ou em SELECTDeclarações críticas de missão em que um bloco seria muito prejudicial.

De fato, você arrisca sua integridade. Pode ocorrer que você leia uma linha, que atualmente é usada para ser excluída ou alterada. Também pode parecer que você leu um valor errado. Isso pode ser muito incomum, mas pode acontecer. O que eu quero dizer com isso? Bem, pense em uma linha que é muito ampla (tem muitas colunas com muitas colunas longas nvarchar). Uma atualização ocorre nesta linha e define novos valores. Em casos raros, pode acontecer com você, que você lê apenas meia linha. Outra coisa pode acontecer, por exemplo, se um usuário alterar seus valores de login. Ele muda seu e-mail + senha. O email já está definido, mas a senha não está. Dessa forma, você tem um estado inconsistente.

Eu sugeriria esquecer READ UNCOMMITTED. Basta usá-lo onde for realmente necessário.

Outra alternativa para você pode ser ativar a READ_COMMITTED_SNAPSHOTopção de banco de dados - portanto, você pode usá-lo READ COMMITTED SNAPSHOTdevido ao controle de versão de linha ativado em seu tempdb. Dessa forma, você acabou de ler outra versão (mais antiga) de uma linha. Isso não bloqueará suas consultas. Mas pode ocorrer que você leia um valor antigo também, mas um valor antigo consistente.

Outra idéia pode ser em WITH(READPAST)vez de WITH(NOLOCK). Você lerá o estado antigo da tabela (um pouco como no exemplo SNAPSHOT ISOLATION), mas ignorará todas as linhas atualmente bloqueadas.

Ionic
fonte
@Ionic, muito obrigado pela resposta! Eu realmente aprecio a ajuda nisso.
dmoney
@HingeSight, parece que sim, mas há uma chance muito boa de que tenha sido minha interpretação da afirmação, de qualquer forma, obrigado pela sua contribuição.
dmoney
1
SNAPSHOT ISOLATIONnão precisa ser ativado para ativar READ COMMITTED SNAPSHOT. Somente a READ COMMITTED SNAPSHOTopção de banco de dados precisa ser ativada para que o controle de versão de linha, em vez de bloquear, tenha consistência de leitura, evitando a necessidade de leituras sujas.
Dan Guzman
Sim, eu quis dizer que @DanGuzman. Desculpe, a resposta foi um pouco clara nesse ponto. Eu editei. :-)
Ionic
Com READPAST você vai ignorar registros que estão bloqueados, você não vai obter os valores antigos - de modo que o único lugar que eu descobri que poderia ser usada é a manipulação da fila
James Z
2

Como declara a resposta aceita, esqueça de usar o nível de isolamento READ UNCOMMITTED (exceto quando realmente necessário), pois você corre o risco de ler dados errados. Mas, para responder ao terceiro ponto da sua pergunta, há duas situações que acho úteis:

  1. Ao gravar e testar pacotes SSIS do SQL Server, as etapas do pacote podem ser agrupadas em uma transação. Se você estiver testando um pacote executando-o passo a passo no depurador SSIS, convém examinar as tabelas enquanto houver bloqueios na tabela. O uso do SET TRANSACTION ISOLATION LEIT UNCOMMITTED permite usar o SQL Server Manager Studio para examinar as tabelas enquanto o pacote está sendo depurado.

  2. No SQL Server Manager Studio, convém testar o código T-SQL agrupando-o em uma transação para oferecer a opção de reverter as alterações. Por exemplo, em um banco de dados de teste, convém restaurar os dados para o estado inicial como parte do seu teste. Se você estiver testando o código agrupado por transação e quiser verificar as tabelas bloqueadas enquanto a transação estiver em andamento, poderá usar SET TRANSACTION ISOLATION LEAD LEIT UNCOMMITTED para examinar os valores em outra janela.

Eu aceito que esses usos sejam bastante obscuros para o Read Read, mas eu os achei úteis em um ambiente de teste.

Ubercoder
fonte
1

Na maioria dos bancos de dados, a grande maioria das atividades, mesmo inserções, exclusões e atualizações, está fora de transações explícitas.

Claro, READ UNCOMMITTED(Dirty Reads) pode fornecer informações incorretas nesses casos, mas essas informações estavam corretas 5 segundos antes.

Os momentos em que as Dirty Reads produzem resultados realmente ruins são quando uma transação falha e precisa ser revertida ou ao executar uma consulta em duas tabelas que normalmente são atualizadas juntas usando uma transação explícita.

Enquanto isso, em um banco de dados grande e ocupado típico que possui uma proporção de 100 (ou mais) para 1 de leituras para gravações, TODAS as consultas únicas (de leitura) que não usam Dirty Reads estão tornando o sistema lento porque ele precisa obter e verificar para bloqueios E está tornando muito mais provável que as transações falhem (geralmente devido a deadlocks), o que pode causar problemas mais sérios de integridade do banco de dados.

Em vez disso, o uso de leituras sujas torna o sistema MUITO mais rápido e mais confiável (em parte devido ao desempenho aprimorado, tornando menos provável a ocorrência de inconsistências).

Claro, há momentos em que eles não devem ser usados. Não gosto de definir o banco de dados como padrão para usar o READ UNCOMMITTEDnível de isolamento ou mesmo usar a SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDinstrução explícita no início dos scripts SQL e SPs - há muitas chances de que uma leitura suja ocorra quando não deveria. Em vez disso, as (NOLOCK)dicas são uma abordagem muito melhor, pois indicam explicitamente que o programador pensou no que estavam fazendo e decidiu que, para esta tabela específica nesta consulta específica, as Dirty Reads eram seguras.

Se você estiver programando um aplicativo para transferir dinheiro de uma conta bancária para outra, não deverá usar Dirty Reads. Mas a maioria dos aplicativos não precisa desse nível de paranóia.

Simon Holzman
fonte