A maioria do fórum e exemplo on-line sempre sugere ter ambos ALLOW_SNAPSHOT_ISOLATION
e READ_COMMITTED_SNAPSHOT
definir como LIGADO sempre que alguém estiver fazendo um instantâneo, controle de versão de linha ou pergunta semelhante.
Acho que a palavra INSTANTÂNEO em ambas as configurações fica um pouco confusa. Eu pensei que, para que o mecanismo de banco de dados usasse o controle de versão de linha em vez de bloqueios para o comportamento padrão READ_COMMITTED, o banco de dados READ_COMMITTED_SNAPSHOT
é definido como ON, independentemente de qual ALLOW_SNAPSHOT_ISOLATION
configuração.
A ALLOW_SNAPSHOT_ISOLATION
configuração é definida como ON somente para permitir o isolamento de instantâneo ao iniciar uma transação (por exemplo, SET TRANSACTION ISOLATION LEVEL SNAPSHOT) independentemente da READ_COMMITTED_SNAPSHOT
configuração.
A única razão para ter essas duas configurações definidas como ON é quando ele precisa ter o controle de versão de linha READ COMMITTED E o isolamento de instantâneo.
Minha pergunta é, meu entendimento está incorreto de alguma forma? E que essas duas configurações devem ser sempre definidas como ON juntas (especialmente para o versionamento de linhas READ COMMITTED)?
Seu entendimento está correto. Fica um pouco confuso.
Kim Tripp (um dos programadores do SQL Server e parte integrante do SQLSkills) passa exatamente pelo que você afirmou nos vídeos do MCM no Snapshot Isolation ( link direto para download MP4 (544MB) ). Avance rápido para 41:45 no vídeo para chegar à parte em que ela responde à sua pergunta.
Se você usar
ALLOW_SNAPSHOT_ISOLATION
certifique-se de usarSET TRANSACTION ISOLATION LEVEL SNAPSHOT
em seu código, caso contrário você não obterá nenhum dos benefícios.Se você definir
SET READ_COMMITTED_SNAPSHOT ON
, não será necessário modificar nenhum código. O MS SQL Server aplica automaticamente o isolamento de instantâneo para essa tabela.Eu não testei para ver o que acontece se você solicitar um nível de isolamento diferente em seu código, suspeito que ele substituirá essa opção, mas teste-o primeiro.
Uma rápida olhada na sobrecarga de desempenho usando o isolamento de instantâneo.
Bom artigo sobre como o isolamento de instantâneo pode alterar o comportamento esperado do seu aplicativo . Ele mostra exemplos de como uma instrução de atualização e uma instrução de seleção podem retornar resultados totalmente diferentes e inesperados.
OK, voltei para casa e testei. Aqui fica a observação.
Primeiro teste com ambas as configurações confirmadas como OFF.
Consulta 1
Consulta 2
Neste teste, a consulta 2 está aguardando a confirmação da consulta 1, dm_tran_locks DMV mostra esse bloqueio exclusivo na TABELA1 incorrido pela consulta 1.
Segundo teste , reverta a transação anterior, defina READ_COMMITTED_SNAPSHOT como LIGADO, mas deixe ALLOW_SNAPSHOT_ISOLATION DESLIGADO.
Execute a consulta 1 e execute a consulta 2. DMV mostra que a consulta 1 incorre em bloqueio exclusivo, mas a consulta 2 retorna detalhes com 'Original' sem que a consulta 1 confirme a transação. Parece que o controle de versão de linha READ_COMMITTED está em vigor.
Adicionar
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
na consulta 1 e na consulta 2 e executar a consulta 1 ou a consulta 2 retorna erro - Falha na transação de isolamento de instantâneo ao acessar o banco de dados 'TEST' porque o isolamento de instantâneo não é permitido neste banco de dados. Use ALTER DATABASE para permitir o isolamento de instantâneo.Terceiro teste , reversão da transação anterior. Defina READ_COMMITTED_SNAPSHOT OFF e ALLOW_SNAPSHOT_ISOLATION ON.
Execute a consulta 1 e, em seguida, a consulta 2. A DMV mostra o bloqueio exclusivo incorrido pela consulta 1. A consulta 2 parece estar aguardando a conclusão da consulta 1. Ativar ALLOW_SNAPSHOT_ISOLATION não parece habilitar o controle de versão de linha READ COMMITTED.
Adicionando
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
à consulta 1 e à consulta 2. Execute a consulta 1 e, em seguida, a consulta 2. Enquanto o DMV mostra que a consulta 1 incorre em bloqueio exclusivo, a consulta 2 retorna os detalhes com 'Original'. O isolamento de instantâneo parece estar em vigor.A observação do teste mostra que
READ_COMMITTED_SNAPSHOT
ele mesmo habilita/desabilita o versionamento de linha READ COMMITTED independentemente daALLOW_SNAPSHOT_ISOLATION
configuração e vice-versa.Seu entendimento está correto. Eu gosto da definição curta, limpa e simples daqui :
Parece que muito mal-entendido vem da própria MS. Por exemplo, aqui eles dizem:
Mas o mencionado "isolamento instantâneo" não é igual ao comportamento da transação para a qual
set transaction isolation level snapshot
é aplicado.Quanto à diferença, uma boa explicação está aqui .
Provavelmente seria melhor se READ_COMMITTED_SNAPSHOT fosse nomeado como READ_COMMITTED_ROW_VERSIONING ou algo assim. :)
Eu gosto deste resumo da Microsoft :