it-swarm.com.de

ALLOW_SNAPSHOT_ISOLATION und READ_COMMITTED_SNAPSHOT

Die meisten Online-Foren und Beispiele empfehlen immer, beide ALLOW_SNAPSHOT_ISOLATION und READ_COMMITTED_SNAPSHOT auf ON setzen, wenn jemand einen Schnappschuss, eine Zeilenversionierung oder eine ähnliche Frage stellt.

Ich denke, das Wort SNAPSHOT in beiden Einstellungen wird etwas verwirrend. Ich dachte, damit die Datenbank-Engine die Zeilenversionierung anstelle von Sperren für das Standardverhalten von READ_COMMITTED verwendet, muss die Datenbank READ_COMMITTED_SNAPSHOT ist auf ON gesetzt nabhängig von was ALLOW_SNAPSHOT_ISOLATION Einstellung.

Das ALLOW_SNAPSHOT_ISOLATION Die Einstellung ist nur auf ON gesetzt, um die Snapshot-Isolation beim Starten einer Transaktion zu ermöglichen (z. B. SET TRANSACTION ISOLATION LEVEL SNAPSHOT) nabhängig von READ_COMMITTED_SNAPSHOT Einstellung.

Der einzige Grund, diese beiden Einstellungen auf ON zu setzen, besteht darin, dass die Zeilenversionierung von READ COMMITTED UND Snapshot-Isolation erforderlich ist.

Meine Frage ist, ist mein Verständnis in irgendeiner Weise falsch? Und dass diese beiden Einstellungen immer zusammen auf ON gesetzt werden müssen (insbesondere für die READ COMMITTED-Zeilenversionierung)?

40
Travis

Du hast das richtig verstanden. Es wird ein wenig verwirrend.

Kim Tripp (einer der Programmierer von SQL Server und ein integraler Bestandteil von SQLSkills) geht genau das durch, was Sie in den MCM-Videos zur Snapshot-Isolation angegeben haben. Schnell vorwärts zu 41:45 im Video, um zu dem Teil zu gelangen, in dem sie Ihre Frage beantwortet.

Wenn du benutzt ALLOW_SNAPSHOT_ISOLATION stellen Sie sicher, dass Sie SET TRANSACTION ISOLATION LEVEL SNAPSHOT in Ihrem Code, sonst erhalten Sie keinen der Vorteile.

Wenn Sie SET READ_COMMITTED_SNAPSHOT ON, dann muss kein Code geändert werden. MS SQL Server wendet automatisch die Snapshot-Isolation für diese Tabelle an.

Ich habe nicht getestet, was passiert, wenn Sie nach einer anderen Isolationsstufe in Ihrem Code fragen. Ich vermute, dass diese Option überschrieben wird, aber testen Sie sie zuerst.

Ein kurzer Überblick über den Leistungsaufwand mithilfe der Snapshot-Isolierung.

Guter Artikel darüber, wie die Snapshot-Isolation das erwartete Verhalten Ihrer App ändern kann . Es werden Beispiele gezeigt, wie eine Update-Anweisung und eine Select-Anweisung völlig unterschiedliche und unerwartete Ergebnisse liefern können.

26
Ali Razeghi

OK, ging nach Hause und testete. Hier ist die Beobachtung.

CREATE DATABASE TEST;
GO
CREATE TABLE TABLE1
(
    ID tinyint,
    Details varchar(10)
);
GO
INSERT INTO TABLE1
VALUES (1, 'Original');
GO

SELECT
    name,
    snapshot_isolation_state_desc,
    is_read_committed_snapshot_on
FROM sys.databases
WHERE name = 'TEST';
GO

Erster Test mit beiden Einstellungen als AUS bestätigt.

Abfrage 1

USE TEST;

BEGIN TRAN
UPDATE TABLE1
SET Details = 'Update'
WHERE ID = 1;

--COMMIT;
--ROLLBACK;
GO

Abfrage 2

USE TEST;

SELECT ID, Details
FROM TABLE1
WHERE ID = 1;
GO

In diesem Test wartet Abfrage 2 auf das Festschreiben von Abfrage 1, dm_tran_locks DMV zeigt die exklusive Sperre für TABELLE 1 an, die bei Abfrage 1 auftritt.

USE TEST;

SELECT
    DB_NAME(tl.resource_database_id) AS DBName,
    resource_type,
    OBJECT_NAME(resource_associated_entity_id) AS tbl_name,
    request_mode,
    request_status,
    request_session_id
FROM sys.dm_tran_locks tl
WHERE 
    resource_database_id = db_id('TEST')
    AND resource_type = 'OBJECT'

Zweiter Test, vorherige Transaktion zurücksetzen, READ_COMMITTED_SNAPSHOT auf ON setzen, aber ALLOW_SNAPSHOT_ISOLATION OFF lassen.

ALTER DATABASE TEST
SET READ_COMMITTED_SNAPSHOT ON
WITH ROLLBACK IMMEDIATE;
GO

Führen Sie Abfrage 1 aus und führen Sie Abfrage 2 aus. DMV zeigt an, dass Abfrage 1 eine exklusive Sperre aufweist, aber Abfrage 2 gibt Details mit 'Original' zurück, ohne dass Abfrage 1 die Transaktion festschreibt. Es scheint, dass die Zeilenversionierung von READ_COMMITTED vorhanden ist.

Hinzufügen von SET TRANSACTION ISOLATION LEVEL SNAPSHOT; bei Abfrage 1 und Abfrage 2 und Ausführen von Abfrage 1 oder Abfrage 2 gibt einen Fehler zurück - Die Snapshot-Isolationstransaktion konnte nicht auf die Datenbank 'TEST' zugreifen, da die Snapshot-Isolation in dieser Datenbank nicht zulässig ist. Verwenden Sie ALTER DATABASE, um die Snapshot-Isolation zu ermöglichen.

Dritter Test, vorherige Transaktion zurücksetzen. Setzen Sie READ_COMMITTED_SNAPSHOT OFF und ALLOW_SNAPSHOT_ISOLATION ON.

ALTER DATABASE TEST
SET READ_COMMITTED_SNAPSHOT OFF
WITH ROLLBACK IMMEDIATE;
GO

ALTER DATABASE TEST
SET ALLOW_SNAPSHOT_ISOLATION ON;
GO

Führen Sie Abfrage 1 und dann Abfrage 2 aus. DMV zeigt die exklusive Sperre von Abfrage 1 an. Abfrage 2 scheint auf den Abschluss von Abfrage 1 zu warten. Das Aktivieren von ALLOW_SNAPSHOT_ISOLATION scheint die READ COMMITTED-Zeilenversionierung nicht zu aktivieren.

Hinzufügen von SET TRANSACTION ISOLATION LEVEL SNAPSHOT; für Abfrage 1 und Abfrage 2. Führen Sie Abfrage 1 und dann Abfrage 2 aus. Während DMV anzeigt, dass Abfrage 1 eine exklusive Sperre aufweist, gibt Abfrage 2 Details mit 'Original' zurück. Die Snapshot-Isolation scheint vorhanden zu sein.

Die Beobachtung aus dem Test zeigt, dass READ_COMMITTED_SNAPSHOT selbst aktiviert/deaktiviert die READ COMMITTED-Zeilenversionierung unabhängig von ALLOW_SNAPSHOT_ISOLATION Einstellung und umgekehrt.

15
Travis

Du hast das richtig verstanden. Ich mag die kurze, saubere und einfache Definition von hier :

Wenn die Datenbankoption READ_COMMITTED_SNAPSHOT aktiviert ist, verwenden Transaktionen, die die isolierte Leseisolationsstufe festlegen, die Zeilenversionierung.

Wenn die Datenbankoption ALLOW_SNAPSHOT_ISOLATION aktiviert ist, können Transaktionen die Isolationsstufe für Snapshots festlegen.

Es scheint, als ob viele Missverständnisse von MS selbst herrühren. Zum Beispiel hier sie sagen:

Wenn Sie die Datenbankoption READ_COMMITTED_SNAPSHOT auf ON setzen, verwendet das Datenbankmodul standardmäßig die Zeilenversionierung und die Snapshot-Isolation , anstatt Sperren zum Schutz der Daten zu verwenden.

Die erwähnte "Snapshot-Isolation" entspricht jedoch nicht dem Verhalten einer Transaktion, für die set transaction isolation level snapshot wird angewandt.

Was den Unterschied betrifft, ist die nette Erklärung hier .

Wahrscheinlich wäre es besser, wenn READ_COMMITTED_SNAPSHOT als READ_COMMITTED_ROW_VERSIONING oder so ähnlich benannt würde. :) :)

4
o.v

Ich mag diese Zusammenfassung von Microsoft :

Durch Festlegen der Option READ_COMMITTED_SNAPSHOT ON können Sie auf versionierte Zeilen unter der Standardisolationsstufe READ COMMITTED zugreifen. Wenn die Option READ_COMMITTED_SNAPSHOT auf OFF gesetzt ist, müssen Sie die Snapshot-Isolationsstufe für jede Sitzung explizit festlegen, um auf versionierte Zeilen zugreifen zu können.

0
flam3