Partilhar via


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

O controle de versão de linha é uma estrutura geral do SQL Server utilizada para fazer o seguinte:

  • Compilar as tabelas inseridas e excluídas em gatilhos. Qualquer linha modificada pelo gatilho tem controle de versão. Isso inclui as linhas modificadas pela instrução que iniciou lançou o gatilho, bem como qualquer modificação de dados feita pelo gatilho.

  • Oferecer suporte a vários conjuntos de resultados ativos (MARS) Se uma sessão MARS emitir uma instrução de modificação de dados (como INSERT, UPDATE ou DELETE) cada vez que houver um conjunto de resultados ativos, as linhas afetadas pela instrução de modificação terão controle de versão.

  • Oferecer suporte a operações de índice que especificam a opção ONLINE.

  • Oferecer suporte a níveis de isolamento de transação com base em controle de versão de linha:

    • Uma nova implementação de nível de isolamento de leitura confirmada que utiliza o controle de versão de linha para fornecer a consistência de leitura em nível de instrução.

    • Um novo nível de isolamento, instantâneo, para fornecer a consistência de leitura em nível de transação.

O banco de dados tempdb deve ter espaço suficiente para o armazenamento de versão. Quando tempdb está completo, as operações de atualização param de gerar versões e continuam a ter êxito, mas as operações de leitura podem falhar porque uma versão de linha específica necessária não existe mais. Isto afeta operações como gatilhos, MARS e indexação online. Para obter mais informações, consulte Uso do recurso de controle de versão de linha.

O uso de controle de versão para transações de leitura confirmada e de instantâneo é um processo em duas etapas:

  1. Defina uma ou ambas as opções de banco de dados READ_COMMITTED_SNAPSHOT e ALLOW_SNAPSHOT_ISOLATION como ON.

  2. Defina o nível de isolamento da transação apropriado em um aplicativo:

    • Quando a opção de banco de dados READ_COMMITTED_SNAPSHOT for ON, as transações que configuram o nível de isolamento da leitura confirmada usarão o controle de versão.

    • Quando a opção de banco de dados ALLOW_SNAPSHOT_ISOLATION for ON, as transações poderão definir o nível de isolamento do instantâneo.

Quando a opção de banco de dados READ_COMMITTED_SNAPSHOT ou ALLOW_SNAPSHOT_ISOLATION for ON, o Mecanismo de Banco de Dados do SQL Server atribuirá um número de seqüência da transação (XSN) para cada transação que manipular dados usando o controle de versão. As transações iniciam quando uma instrução BEGIN TRANSACTION é executada. Porém, o número de seqüência da transação inicia com a primeira operação de leitura ou gravação depois da instrução BEGIN TRANSACTION. O número de seqüência da transação é incrementado um por vez sempre que é atribuído.

Quando as opções de banco de dados READ_COMMITTED_SNAPSHOT ou ALLOW_SNAPSHOT_ISOLATION forem ON, as cópias lógicas (versões) serão mantidas para todas as modificações de dados executadas no banco de dados. Cada vez que uma linha é modificada por uma transação específica, a instância do Mecanismo de Banco de Dados armazena uma versão da imagem anteriormente confirmada da linha em tempdb. Cada versão é marcada com o número de seqüência de transação da transação que fez a alteração. As versões das linhas modificadas são encadeadas usando uma lista de links. O valor da linha mais recente sempre é armazenado no banco de dados atual e encadeado às linhas com controle de versão armazenadas em tempdb.

ObservaçãoObservação

Para modificação de LOBs (Objetos Grandes), somente o fragmento alterado é copiado para o armazenamento de versão em tempdb.

As versões da linha são mantidas por tempo suficiente para atender os requisitos das transações executadas em níveis de isolamento com base em controle de versão de linha. O Mecanismo de Banco de Dados localiza o número útil mais antigo de seqüência da transação e exclui periodicamente todas as versões da linha carimbadas com números de seqüência da transação inferiores ao número útil mais antigo da seqüência.

Quando ambas as opções do banco de dados estão definidas como OFF, somente as linhas modificadas por gatilhos ou sessões MARS, ou lidas por operações de índice ONLINE, têm controle de versão. Essas versões de linha são liberadas quando já não são necessárias. Um thread em segundo plano é periodicamente executado para remover versões obsoletas da linha.

ObservaçãoObservação

Para transações de curta duração, uma versão de uma linha modificada pode ficar armazenada em cache no pool de buffers sem ter sido gravada nos arquivos de disco do banco de dados tempdb. Se a necessidade da linha com controle de versão for de curta duração, a linha será simplesmente retirada do pool de buffers sem necessariamente gerar uma sobrecarga de E/S.

Comportamento durante a leitura de dados

Quando as transações são executadas em dados de leitura de isolamento com base em controle de versão de linha, as operações de leitura não adquirem bloqueios compartilhados (S) nos dados que estão sendo lidos, portanto, não bloqueiam transações que estão modificando dados. A sobrecarga de recursos de bloqueio também é minimizada conforme o número de bloqueios adquirido é reduzido. O isolamento de leitura confirmada que usa controle de versão de linha e isolamento de instantâneo é desenvolvido para fornecer consistências de leitura em nível de transação e instrução de dados com controle de versão.

Todas as consultas, incluindo as transações executadas em níveis de isolamento com base em controle de versão de linha, adquirem bloqueios Sch-S (estabilidade do esquema) durante a compilação e a execução. Por causa disso, as consultas são bloqueadas quando uma transação simultânea mantém um bloqueio Sch-M (modificação de esquema) na tabela. Por exemplo, uma operação DDL (Linguagem de Definição de Dados) adquire um bloqueio Sch-M antes de modificar a informação do esquema da tabela. As transações de consulta, incluindo aquelas executadas em nível de isolamento com base em controle de versão de linha, são bloqueadas ao tentar adquirir um bloqueio Sch-S. Da mesma forma, uma consulta que mantém um bloqueio Sch-S bloqueia uma transação simultânea que tenta adquirir um bloqueio Sch-M. Para obter mais informações sobre comportamento do bloqueio, consulte Compatibilidade de bloqueios (Mecanismo de Banco de Dados).

Quando uma transação que usa o nível de isolamento do instantâneo é iniciada, a instância do Mecanismo de Banco de Dados registra todas as transações atualmente ativas. Quando a transação de instantâneo lê uma linha que tem uma cadeia de versão, o Mecanismo de Banco de Dados segue a cadeia e recupera a linha em que o número de seqüência da transação:

  • Está mais próxima, mas inferior ao número de seqüência da transação de instantâneo que está lendo a linha.

  • Não está na lista das transações ativas quando a transação de instantâneo é iniciada.

As operações de leitura executadas por uma transação de instantâneo recuperam a última versão de cada linha confirmada quando a transação de instantâneo foi iniciada. Isso fornece um instantâneo transacional consistente dos dados, da mesma forma como existiam no início da transação.

As transações de leitura confirmada que usam controle de versão de linha funcionam praticamente do mesmo modo. A diferença é que a transação de leitura confirmada não usa o seu próprio número de seqüência da transação ao escolher versões de linha. Cada vez que uma instrução é iniciada, a transação de leitura confirmada lê o último número de seqüência da transação emitido para aquela instância do Mecanismo de Banco de Dados. Esse é o número de seqüência da transação usado para selecionar as versões de linha corretas para aquela instrução. Isso permite que as transações de leitura confirmada veja um instantâneo dos dados como ele era no início de cada instrução.

ObservaçãoObservação

Embora as transações de leitura confirmada que usam controle de versão de linha forneçam uma exibição transacional consistente dos dados em um nível de instrução, as versões de linha geradas ou acessadas por esse tipo de transação são mantidas até a conclusão da transação.

Comportamento durante a modificação de dados

Em uma transação de leitura confirmada que usa o controle de versão de linha, a seleção de linhas a serem atualizadas é feita usando uma verificação de bloqueio em que um bloqueio de atualização (U) é feito na linha de dados conforme os valores dos dados são lidos. Isso é igual à transação confirmada por leitura que não usa controle de versão de linha. Se a linha de dados não atender os critérios de atualização, o bloqueio de atualização será liberado naquela linha e a próxima linha será fechada e verificada.

As transações executadas em isolamento de instantâneo usam uma abordagem otimista para modificação de dados adquirindo bloqueios em dados antes de executar a modificação somente para impor restrições. Do contrário, os bloqueios não são adquiridos em dados até que os dados sejam modificados. Quando uma linha de dados atende os critérios de atualização, a transação de instantâneo verifica se a linha de dados não foi modificada por uma transação simultânea que foi confirmada depois do início da transação de instantâneo. Se a linha de dados tiver sido modificada fora da transação de instantâneo, ocorrerá um conflito de atualização e a transação de instantâneo será finalizada. O conflito de atualização é controlado pelo Mecanismo de Banco de Dados e não há como desabilitar a detecção de conflito de atualização.

ObservaçãoObservação

As operações de atualização executadas em isolamento de instantâneo são internamente executadas em isolamento de leitura confirmada quando a transação de instantâneo acessa qualquer um dos seguintes itens:

Uma tabela com uma restrição FOREIGN KEY.

Uma tabela referenciada na restrição FOREIGN KEY de outra tabela.

Uma exibição indexada referenciando mais de uma tabela.

Porém, mesmo de acordo com essas condições, a operação de atualização continuará verificando se os dados não foram modificados por outra transação. Se os dados tiverem sido modificados por outra transação, a transação de instantâneo encontrará um conflito de atualização e será finalizada.

Resumo do comportamento

A tabela a seguir resume as diferenças entre o isolamento de instantâneo e o isolamento de leitura confirmada usando o controle de versão de linha.

Propriedade

Nível de isolamento de leitura confirmada usando o controle de versão de linha

Nível de isolamento do instantâneo

A opção de banco de dados que deve ser definida como ON para habilitar o suporte exigido.

READ_COMMITTED_SNAPSHOT

ALLOW_SNAPSHOT_ISOLATION

Como uma sessão solicita o tipo específico de controle de versão de linha.

Use o nível padrão de isolamento de leitura confirmada ou execute a instrução SET TRANSACTION ISOLATION LEVEL para especificar o nível de isolamento READ COMMITTED. Isso pode ser feito depois do início da transação.

Exige a execução de SET TRANSACTION ISOLATION LEVEL para especificar o nível de isolamento SNAPSHOT antes do início da transação.

A versão dos dados lidos por instruções.

Todos os dados que foram confirmados antes do início de cada instrução.

Todos os dados que foram confirmados antes do início de cada transação.

Como as atualizações são controladas.

Faz a reversão de versões de linha a dados reais para selecionar as linhas que devem ser atualizadas e usa os bloqueios de atualização nas linhas de dados selecionadas. Adquire bloqueios exclusivos em linhas de dados atuais a serem modificadas. Nenhuma detecção de conflito de atualização.

Usa versões de linha para selecionar linhas a serem atualizadas. Tenta adquirir um bloqueio exclusivo na linha de dados reais a ser modificada e, se os dados tiverem sido modificados por outra transação, ocorrerá um conflito de atualização e a transação de instantâneo será finalizada.

Atualização de detecção de conflito.

Nenhum.

Suporte integrado. Não pode ser desabilitado.