NOLOCK = READ UNCOMMITED = Leitura Suja

Trabalhando em alguns sistemas, nos foi recomendado, pelo próprio cliente, que fizéssemos uso do operador NOLOCK em todos os comandos de consulta que fizéssemos no banco de dados. Isso parece uma atitude exagerada, mas por experiência do cliente, com receio de deadlocks, tínhamos de seguir à risca essa indicação.

You no lock?

O SQL Server utiliza recursos de bloqueio (tanto para escrita quanto leitura) para garantir a integridade dos dados. Enquanto executamos uma transação seguimos o conceito ACID (se você não conhece este conceito, veja este post Entity Framework 6 – Database.BeginTransaction() e Database.UseTransaction(DbTransaction)). Por conta disso, dentro de uma transação qualquer comando paralelo que tente acessar os dados com os quais estamos trabalhando entram nesse bloqueio, e assim são forçados a aguardar o término de nossa transação.

O operador NOLOCK ignora esse bloqueio e acessa os dados de qualquer forma, mesmo que alguma transação esteja ocorrendo. O NOLOCK permite a leitura de dados não commitados. Outra forma de obter o mesmo resultado é executando a linha de comando abaixo, assim alterando o nível de isolamento da transação em execução:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

O ponto negativo do uso de NOLOCK ou nível de isolamento READ UNCOMMITED é que eles podem ocasionar em leituras sujas (dirty reads). Leitura suja é o cenário no qual lemos dados que ainda não foram commitados no banco de dados.

Ler dados não commitados não é nada bom, pois nada impede que esses dados sejam revertidos (por meio de um comando ROLLBACK) e nos deixem “dados sujos nas mãos”.

Por isso ressalvo que é preciso estudar a utilização de cada comando, cada parâmetro e cada operador de qualquer linguagem, banco de dados ou tecnologia, para assim verificar se ele é aceitável ou não em sua aplicação.

Geralmente esse é o sentimento quando encontramos esse tipo de cenário…

Não tem para onde correr

O Entity Framework não faz uso do operador NOLOCK, mas suporta a alteração do nível de isolamento para READ UNCOMMITED.

Com o Entity Framework 6, nós podemos fazer uso do método BeginTransaction(), e construir algo como o bloco de código abaixo:

using (var context = new ProgramContext()) {

    using (var tran = context.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted)) {

        var query = from q1 in context.FlightAttendants
                    where q1.Company != null && q1.Company.Name == "aa"
                    select q1;

        var result = query.ToList();

        tran.Commit();
    }
}

Nas versões anteriores ao Entity Framework 6 isso não é possível, pois o método BeginTransaction() não existe. Mas podemos fazer isso de outras duas formas. A primeira é utilizando a classe TransactionScope:

var transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;

using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions)) {

    using (var context = new ProgramContext()) {

        var query = from q1 in context.FlightAttendants
                    where q1.Company != null && q1.Company.Name == "aa"
                    select q1;

        var result = query.ToList();
    }
}

E a segunda forma é rodando o comando “SET TRANSACTION ISOLATION LEVEL” com a instância ativa do contexto, como apresentado abaixo:

using (var context = new ProgramContext()) {

    context.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");

    var query = from q1 in context.FlightAttendants
                where q1.Company != null && q1.Company.Name == "aa"
                select q1;

    var result = query.ToList();
}

Espero que seja útil.

Por

MSc. Fernando Henrique Inocêncio Borba Ferreira

Microsoft Most Valuable Professional – Visual C#

Referências:

http://www.hanselman.com/blog/GettingLINQToSQLAndLINQToEntitiesToUseNOLOCK.aspx

http://blogs.msdn.com/b/fcatae/archive/2010/10/05/como-usar-select-with-nolock-para-melhorar-a-performance.aspx

Publicidade

4 comentários sobre “NOLOCK = READ UNCOMMITED = Leitura Suja

  1. Tanto de artigos em português, como em inglês essa foi a explicação mais clara que já vi sobre isso,

    Parabéns! Excelente didática.

    ps: imagem legal kkk

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.