Usando níveis de isolamento com base em controle de versão de linha

A estrutura de controle de versão de linha permanece sempre habilitada no SQL Server e é usada por vários recursos. Além de fornecer níveis de isolamento com base em controle de versão de linha, ela é usada para oferecer suporte a modificações feitas em gatilhos e em sessões MARS (Multiple Active Result Sets), e para oferecer suporte à leitura de dados de operações de índice ONLINE.

Os níveis de isolamento com base em controle de versão de linha são habilitados no banco de dados. Todos os aplicativos que acessam os objetos de bancos de dados habilitados podem executar consultas usando os seguintes níveis de isolamento:

  • Confirmado para leitura que usa controle de versão de linha pela definição da opção de banco de dados READ_COMMITTED_SNAPSHOT como ON, como mostrado no seguinte exemplo de código:

    ALTER DATABASE AdventureWorks2008R2
        SET READ_COMMITTED_SNAPSHOT ON;
    

    Quando o banco de dados está habilitado para READ_COMMITTED_SNAPSHOT, todas as consultas no nível de isolamento confirmado para leitura usam controle de versão de linha, o que significa que as operações de leitura não bloqueiam as operações de atualização.

  • Isolamento do instantâneo através da definição da opção de banco de dados ALLOW_SNAPSHOT_ISOLATION como ON, como mostrado no exemplo de código seguinte:

    ALTER DATABASE AdventureWorks2008R2
        SET ALLOW_SNAPSHOT_ISOLATION ON;
    

    Uma transação executada em isolamento de instantâneo pode acessar tabelas do banco de dados habilitadas para instantâneo. Para acessar tabelas que não foram habilitadas para instantâneo, é preciso alterar o nível de isolamento. Por exemplo, o exemplo de código a seguir mostra uma instrução SELECT que une duas tabelas durante a execução de uma transação de instantâneo. Uma das tabelas pertence a um banco de dados no qual o isolamento de instantâneo não está habilitado. Quando a instrução SELECT for executada no isolamento de instantâneo, não será executada com êxito.

    SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
    BEGIN TRAN
        SELECT t1.col5, t2.col5
            FROM Table1 as t1
            INNER JOIN SecondDB.dbo.Table2 as t2
                ON t1.col1 = t2.col2;
    

    O exemplo de código a seguir mostra a mesma instrução SELECT que foi modificada para alterar o nível de isolamento da transação para confirmado para leitura. Em razão dessa mudança, a instrução SELECT será executada com êxito.

    SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
    BEGIN TRAN
        SELECT t1.col5, t2.col5
            FROM Table1 as t1
            WITH (READCOMMITTED)
            INNER JOIN SecondDB.dbo.Table2 as t2
                ON t1.col1 = t2.col2;
    

Para obter mais informações sobre como definir o nível de isolamento em um aplicativo, consulte Ajustando níveis de isolamento da transação.

Limitações de transações usando níveis de isolamento com base em controle de versão de linha

Considere as limitações seguintes ao trabalhar com níveis de isolamento com base em controle de versão de linha:

  • READ_COMMITTED_SNAPSHOT não pode ser habilitada em tempdb, msdb, nem em master.

  • As tabelas temporárias globais são armazenadas em tempdb. Ao acessar tabelas temporárias globais em uma transação de instantâneo, uma das seguintes ações deve ocorrer:

    • Defina a opção de banco de dados ALLOW_SNAPSHOT_ISOLATION como ON em tempdb.

    • Use uma dica de isolamento para alterar o nível de isolamento da instrução.

  • Transações de instantâneo falham quando:

    • O banco de dados é transformado em somente leitura após o início da transação de instantâneo, mas antes que a transação de instantâneo acesse o banco de dados.

    • Se objetos forem acessados em vários bancos de dados, um estado de banco de dados terá sido alterado de tal modo que a recuperação do banco de dados ocorrerá após o início da transação de instantâneo, mas antes que a transação de instantâneo acesse o banco de dados. Por exemplo: o banco de dados foi definido como OFFLINE e depois como ONLINE; o banco de dados fecha automaticamente e se abre ou o banco de dados é desanexado e anexado.

  • Não há suporte para transações distribuídas, inclusive consultas em bancos de dados particionados distribuídos em isolamento de instantâneo.

  • SQL Server não mantém versões múltiplas de metadados de sistema. As instruções DDL (Linguagem de Definição de Dados) em tabelas e em outros objetos de banco de dados (índices, exibições, tipos de dados, procedimentos armazenados e funções CLR (Common Language Runtime)) alteram metadados. Se uma instrução DDL modificar um objeto, qualquer referência simultânea ao objeto em isolamento de instantâneo fará com que a transação de instantâneo falhe. Transações confirmadas para leitura não têm essa limitação quando a opção de banco de dados READ_COMMITTED_SNAPSHOT é ON.

    Por exemplo, um administrador de banco de dados executa a instrução ALTER INDEX a seguir.

    USE AdventureWorks2008R2;
    GO
    ALTER INDEX AK_Employee_LoginID
        ON HumanResources.Employee REBUILD;
    GO
    

    Qualquer transação de instantâneo que esteja ativa quando a instrução ALTER INDEX for executada receberá um erro, caso ela tente fazer referência à tabela HumanResources.Employee após a execução da instrução ALTER INDEX. As transações confirmadas para leitura que usam controle de versão de linha não são afetadas.

    ObservaçãoObservação

    As operações BULK INSERT podem causar alterações a metadados da tabela de destino (por exemplo, ao desabilitar verificações de restrição). Quando isso ocorre, as transações de isolamento de instantâneo simultâneas que acessam tabelas inseridas em massa falham.