Eu uso SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
na maioria das minhas consultas SQL gerais, principalmente porque isso foi detalhado para mim quando originalmente aprendi a linguagem.
Do meu entendimento, esse nível de isolamento age da mesma maneira que WITH (NO LOCK)
, no entanto, eu só costumo usar arquivos SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
.
- Existe algum momento que eu deveria estar usando
WITH (NO LOCK)
maisSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
. - Isso
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
impede que outros usuários sejam bloqueados nas tabelas que estou lendo? - Se
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
é usado para parar bloqueios, mas estou apenas lendo dados, qual é o sentido de usá-lo? São apenas as 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 UNCOMMITTED
ao ler dados que seriam usados em atualizações, presumivelmente para evitar a atualização de dados sujos. Seria este o único motivo? - Com o tipo de banco de dados em que estou trabalhando, existe um ambiente de produção e teste. Raramente estaremos consultando o ambiente de produção, mas quando preciso, geralmente estarei usando
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
em minha consulta. Eu entendo que leituras sujas são possíveis com isso. Além de receber dados de volta que podem não ser confirmados no banco de dados (e, portanto, descartar meus resultados), que outros tipos de 'leituras sujas' poderiam ser possíveis?
Desculpe as perguntas em massa.
É terrível, que você aprendeu dessa forma (desculpe!).
READ UNCOMMITTED
vamos ler todas as linhas, sim. Mesmo aqueles que são usados atualmente em uma operaçãoINSERT
,UPDATE
.DELETE
Isso é muito útil se você precisar dar uma olhada rápida em alguns dados ou em declarações de missão críticaSELECT
em que um bloco seria muito prejudicial.Na verdade, você arrisca sua integridade. Pode ocorrer que você leia uma linha, que atualmente é usada para ser excluída ou em uma alteração. Também pode parecer que você leu um valor errado. Isso pode ser realmente incomum, mas pode acontecer. O que 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ê leia 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 e-mail já está definido, mas a senha não. Desta forma, você tem um estado inconsistente.Sugiro esquecer
READ UNCOMMITTED
. Basta usá-lo onde for realmente necessário.Outra alternativa para você pode ser habilitar a
READ_COMMITTED_SNAPSHOT
opção de banco de dados - portanto, você pode usarREAD COMMITTED SNAPSHOT
devido ao versionamento de linha habilitado 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 ideia pode ser
WITH(READPAST)
em vez deWITH(NOLOCK)
. Você lerá o estado antigo da tabela (um pouco como noSNAPSHOT ISOLATION
), mas pulará todas as linhas atualmente bloqueadas.Como afirma 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, existem duas situações que considero úteis:
Ao escrever 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 do SSIS, convém examinar as tabelas enquanto há bloqueios na tabela. O uso de SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED permite usar o SQL Server Manager Studio para examinar as tabelas enquanto o pacote está sendo depurado.
No SQL Server Manager Studio, você pode testar o código T-SQL envolvendo-o em uma transação para oferecer a opção de reverter as alterações. Por exemplo, em um banco de dados de teste, você pode querer restaurar os dados para o estado inicial como parte de seu teste. Se você estiver testando o código encapsulado da transação e desejar verificar as tabelas bloqueadas enquanto a transação estiver em andamento, poderá usar SET TRANSACTION ISOLATION LEVEL LEVEL READ UNCOMMITTED para examinar os valores em outra janela.
Eu aceito que esses são usos bastante obscuros para READ UNCOMMITTED, mas eu os achei úteis em um ambiente de teste.
Na maioria dos bancos de dados, a grande maioria das atividades, mesmo inserções, exclusões e atualizações, está fora das 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 genuinamente 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 tem uma proporção de 100 (ou mais) para 1 de leituras para gravações, CADA consulta (leitura) que não usa Dirty Reads está deixando o sistema lento porque precisa obter e verificar para bloqueios E está tornando muito mais provável que as transações falhem (normalmente 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 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 UNCOMMITTED
nível de isolamento ou até mesmo usar aSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
instrução explícita no início de scripts SQL e SPs - há muita chance de que uma leitura suja aconteça quando não deveria. Em vez disso, as(NOLOCK)
dicas são uma abordagem muito melhor, pois indicam explicitamente que o programador pensou sobre o que estava fazendo e decidiu que, para essa 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 o Dirty Reads. Mas a maioria dos aplicativos não precisa desse nível de paranóia.