INSTANTÂNEO DO NÍVEL DA ISOLAÇÃO DA TRANSAÇÃO contra TRUNCATE?


10

Espero que alguém possa lançar alguma luz sobre esse comportamento que eu não esperava com relação ao isolamento do INSTANTÂNEO vs. TRUNCATE.

Banco de Dados: Permitir Isolamento de Instantâneo = Verdadeiro; É instantâneo confirmado leitura ativado = falso.

Procedimento1 (Substitui o conteúdo da tabela foo de um SELECT complexo de longa execução por muitas junções):

BEGIN TRAN; 
TRUNCATE TABLE foo; 
INSERT INTO foo SELECT...; 
COMMIT;

Procedimento2 (Lê da tabela foo):

SET TRANSACTION ISOLATION LEVEL SNAPSHOT; 
SELECT * FROM foo;

Se o Procedimento1 estiver em execução enquanto o Procedimento2 for executado, o Procedimento2 será mantido com uma espera LCK_M_SCH_S (de acordo com sp_WhoIsActive) até que o Procedimento1 seja concluído. E quando o Procedimento2 é concluído, gera esta exceção:

A transação de isolamento de captura instantânea falhou no banco de dados 'DatabaseName' porque o objeto acessado pela instrução foi modificado por uma instrução DDL em outra transação simultânea desde o início desta transação. Não é permitido porque os metadados não estão com versão. Uma atualização simultânea de metadados pode levar à inconsistência se combinada com o isolamento de captura instantânea.

No entanto, a Microsoft não lista TRUNCATE como uma instrução DDL não permitida no isolamento do INSTANTÂNEO: http://msdn.microsoft.com/en-us/library/bb933783.aspx

Claramente, não estou entendendo algo corretamente, pois eu esperaria que um melhor caso de Procedure2 retornasse imediatamente os dados confirmados mais recentemente da tabela antes do TRUNCATE ou um pior caso de ser mantido pelo Procedure1 e, em seguida, retornasse o novo conteúdo do tabela. Você pode ajudar?


Você pode usar DELETE FROM foo? Isso não colocará o bloqueio do esquema.
precisa saber é o seguinte

DELETE FROM é realmente a maneira como estou trabalhando com isso. Também estou interessado em saber por que estou recebendo o erro (e somente depois que o Procedimento1 retornar).
Mark Freeman

Respostas:


19

A lista de 'DDL'operações listadas não é abrangente (e TRUNCATE TABLEnão é a única omissão dessa lista). Se TRUNCATE TABLEé DMLou DDLé uma questão preocupante em SQL Server, com exemplos convincentes de ambos os lados do debate, e entradas para os dois lados em Books Online.

Do ponto de vista de uma transação de isolamento de captura instantânea, truncar tem a qualidade essencial de obter um Sch-Mbloqueio , o que explica o bloqueio (porque RCSIe SIainda adquire Sch-Sbloqueios ); e também colide com a versão interna de metadados (por motivos internos *), resultando no erro 3961.

Portanto, o comportamento que você está vendo é esperado, apenas não muito bem documentado.

* A implementação atual do TRUNCATE TABLE não gera versões de linha. Compartilhar a versão de metadados é a maneira mais simples de garantir o comportamento correto.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.