TRANSACTION ISOLATION LEVEL SNAPSHOT vs. TRUNCATE?


10

Ich hoffe, jemand kann etwas Licht in dieses Verhalten bringen, das ich in Bezug auf SNAPSHOT-Isolation vs. TRUNCATE nicht erwartet hatte.

Datenbank: Snapshot-Isolation zulassen = True; Wird gelesen Festgeschriebener Schnappschuss Ein = Falsch.

Prozedur1 (Ersetzt den Inhalt der Tabelle foo aus einem langjährigen komplexen SELECT durch viele Verknüpfungen):

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

Prozedur2 (Liest aus Tabelle foo):

SET TRANSACTION ISOLATION LEVEL SNAPSHOT; 
SELECT * FROM foo;

Wenn Prozedur1 ausgeführt wird, während Prozedur2 ausgeführt wird, wird Prozedur2 mit einer LCK_M_SCH_S-Wartezeit (gemäß sp_WhoIsActive) angehalten, bis Prozedur1 beendet ist. Und wenn Prozedur2 abgeschlossen ist, wird diese Ausnahme ausgelöst:

Die Snapshot-Isolationstransaktion ist in der Datenbank 'DatabaseName' fehlgeschlagen, da das Objekt, auf das die Anweisung zugreift, seit dem Start dieser Transaktion durch eine DDL-Anweisung in einer anderen gleichzeitigen Transaktion geändert wurde. Es ist nicht zulässig, da die Metadaten nicht versioniert sind. Eine gleichzeitige Aktualisierung von Metadaten kann zu Inkonsistenzen führen, wenn sie mit der Snapshot-Isolation gemischt werden.

Microsoft listet TRUNCATE jedoch nicht als DDL-Anweisung auf, die unter SNAPSHOT-Isolation nicht zulässig ist: http://msdn.microsoft.com/en-us/library/bb933783.aspx

Offensichtlich verstehe ich etwas nicht richtig, da ich erwartet hätte, dass Prozedur2 die zuletzt festgeschriebenen Daten sofort vor TRUNCATE aus der Tabelle zurückgibt oder dass Prozedur1 im schlimmsten Fall aufgehalten wird und dann den neuen Inhalt von Prozedur1 zurückgibt Tabelle. Kannst du helfen?


Können Sie stattdessen DELETE FROM foo verwenden? Dadurch wird die Schemasperre nicht platziert.
SqlACID

DELETE FROM ist in der Tat die Art und Weise, wie ich daran arbeite. Ich bin auch daran interessiert, warum ich den Fehler erhalte (und erst, nachdem Procedure1 zurückgegeben wurde).
Mark Freeman

Antworten:


19

Die Liste der 'DDL'aufgeführten Vorgänge ist nicht vollständig (und TRUNCATE TABLEnicht die einzige Auslassung in dieser Liste). Ob TRUNCATE TABLEes sich bei SQL Server um eine schwierige Frage handelt DMLoder nicht DDL, mit überzeugenden Beispielen auf beiden Seiten der Debatte und Einträgen in beide Richtungen in Books Online.

Aus der Sicht einer Snapshot - Isolation Transaktion, truncate hat die wesentliche Eigenschaft eine Aufnahme Sch-MSperre , die die Blockierung (da erklärt RCSIund SInoch acquire Sch-SSchlösser ); Außerdem wird die interne Metadatenversion (aus internen Gründen *) gestoßen, was zu Fehler 3961 führt.

Das Verhalten, das Sie sehen, wird also erwartet, nur nicht sehr gut dokumentiert.

* Die aktuelle Implementierung von TRUNCATE TABLE generiert keine Zeilenversionen. Das Bumping der Metadatenversion ist der einfachste Weg, um ein korrektes Verhalten sicherzustellen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.