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?