TRANSACTION ISOLATION LEVEL INSTANTÁNEA vs. TRUNCADO?


10

Espero que alguien pueda arrojar algo de luz sobre este comportamiento que no esperaba con respecto al aislamiento SNAPSHOT frente a TRUNCATE.

Base de datos: Permitir aislamiento de instantánea = verdadero; Se lee la instantánea confirmada activada = Falso.

Procedimiento1 (Reemplaza el contenido de la tabla foo de un complejo SELECT de larga duración con muchas combinaciones):

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

Procedimiento2 (Lecturas de la tabla foo):

SET TRANSACTION ISOLATION LEVEL SNAPSHOT; 
SELECT * FROM foo;

Si el Procedimiento1 se está ejecutando mientras se ejecuta el Procedimiento2, el Procedimiento2 se detiene con una espera LCK_M_SCH_S (de acuerdo con sp_WhoIsActive) hasta que el Procedimiento1 finalice. Y cuando el Procedimiento2 se completa, genera esta excepción:

La transacción de aislamiento de instantánea falló en la base de datos 'DatabaseName' porque el objeto al que accede la declaración ha sido modificado por una declaración DDL en otra transacción concurrente desde el inicio de esta transacción. No está permitido porque los metadatos no están versionados. Una actualización simultánea de los metadatos puede generar inconsistencias si se combina con el aislamiento de instantáneas.

Sin embargo, Microsoft no enumera TRUNCATE como una declaración DDL no permitida bajo el aislamiento SNAPSHOT: http://msdn.microsoft.com/en-us/library/bb933783.aspx

Claramente, no estoy entendiendo algo correctamente, ya que hubiera esperado que el mejor caso del Procedimiento2 devolviera inmediatamente los datos confirmados más recientemente de la tabla antes del TRUNCADO o el peor de los casos en que el Procedimiento1 retrasó y luego devolviera el nuevo contenido del mesa. ¿Puede usted ayudar?


¿Puedes usar DELETE FROM foo en su lugar? Eso no colocará el bloqueo del esquema.
SqlACID

DELETE FROM es de hecho la forma en que estoy trabajando en esto. También estoy interesado en por qué recibo el error (y solo después de que el Procedimiento1 regrese).
Mark Freeman

Respuestas:


19

La lista de 'DDL'operaciones enumeradas no es exhaustiva (y TRUNCATE TABLEno es la única omisión de esa lista). Si TRUNCATE TABLEes DMLo DDLes una pregunta tensa en SQL Server, con ejemplos persuasivos en ambos lados del debate y entradas en ambos sentidos en Books Online.

Desde el punto de vista de una transacción de aislamiento de instantánea, truncado tiene la cualidad esencial de tomar un Sch-Mbloqueo , lo que explica el bloqueo (debido RCSIy SIseguir adquiriendo Sch-Sbloqueos ); y también topa la versión interna de metadatos (por razones internas *), lo que da como resultado el error 3961.

Por lo tanto, se espera el comportamiento que está viendo, pero no está bien documentado.

* La implementación actual de TRUNCATE TABLE no genera versiones de fila. Topar la versión de metadatos es la forma más sencilla de garantizar un comportamiento correcto.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.