Snapshot Isolation vs. Serializable Snapshot Isolation: das letzte Loch schließen
AI generated
SELECT
JOIN
SQL / Temporal Data
Snapshot Isolation vs. Serializable Snapshot Isolation
warum Write Skew das letzte offene Loch ist

Snapshot Isolation gilt zu Recht als komfortabler Kompromiss: Sie verhindert Dirty Reads, Non-repeatable Reads und die meisten Phantom Reads, ohne den Sperraufwand eines vollständigen Serializable-Levels. Trotzdem lässt sie eine subtile, aber gefährliche Anomalie zu, den sogenannten Write Skew, bei dem zwei Transaktionen unabhängig voneinander konsistent erscheinende Entscheidungen treffen, die zusammen eine Geschäftsregel verletzen. Serializable Snapshot Isolation, kurz SSI, schließt genau dieses letzte Loch. Dieser Artikel erklärt beide Isolationsstufen im Detail und arbeitet ein klassisches Write-Skew-Beispiel Schritt für Schritt durch.

12 Min. Lesezeit Snapshot Isolation · SSI Write Skew praktisch erklärt

1. Das Grundprinzip von Snapshot Isolation

Unter Snapshot Isolation sieht jede Transaktion beim ersten Lesezugriff einen konsistenten Schnappschuss der Datenbank, so wie sie zum Startzeitpunkt der Transaktion aussah, und zwar unabhängig davon, welche anderen Transaktionen währenddessen parallel schreiben. Änderungen anderer, gleichzeitig laufender Transaktionen bleiben für die eigene Transaktion unsichtbar, bis diese selbst committet und einen neuen Snapshot beginnt.

Beim Schreiben gilt die Regel First Committer Wins: Versuchen zwei Transaktionen, dieselbe Zeile zu ändern, gewinnt diejenige, die zuerst committet, während die zweite mit einem expliziten Konflikt abgewiesen wird und einen Retry benötigt. Dieser Mechanismus verhindert verlorene Updates zuverlässig, solange sich der Konflikt tatsächlich auf dieselbe physische Zeile bezieht.


-- PostgreSQL: explizit unter Snapshot Isolation arbeiten
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT kontostand FROM konto WHERE konto_id = 1;
-- Snapshot wird beim ersten Read fixiert, spätere parallele
-- Änderungen an anderen Zeilen bleiben für diese Transaktion unsichtbar
UPDATE konto SET kontostand = kontostand - 100 WHERE konto_id = 1;
COMMIT;

2. Welche Anomalien Snapshot Isolation zuverlässig vermeidet

Dirty Reads sind unter Snapshot Isolation grundsätzlich ausgeschlossen, weil eine Transaktion niemals Daten aus einer nicht committeten, parallelen Transaktion sieht. Non-repeatable Reads treten ebenfalls nicht auf, weil derselbe Snapshot für die gesamte Dauer der Transaktion stabil bleibt, ein zweites SELECT auf dieselbe Zeile liefert also garantiert denselben Wert wie das erste.

Auch Phantom Reads werden durch den fixierten Snapshot weitgehend verhindert: Eine Bereichsabfrage liefert innerhalb derselben Transaktion konsistent dieselbe Menge an Zeilen, selbst wenn parallel neue, zum Filter passende Zeilen eingefügt werden. Diese drei klassischen Anomalien aus dem SQL-Standard deckt Snapshot Isolation also vollständig ab, was sie in der Praxis für die meisten Anwendungsfälle bereits ausreichend robust macht.

3. Die Write-Skew-Anomalie: das klassische Beispiel mit dem Bereitschaftsdienst

Das Standardbeispiel für Write Skew stammt aus einem Krankenhaus-Bereitschaftsdienst: Es gibt eine Geschäftsregel, dass mindestens eine Ärztin oder ein Arzt im Dienst sein muss. Zwei diensthabende Personen, Ärztin A und Arzt B, entscheiden unabhängig voneinander, sich krankzumelden. Beide lesen zunächst, wie viele Personen aktuell im Dienst sind, beide sehen zwei, und beide schließen daraus korrekt, dass sich jeweils eine Person abmelden darf, ohne die Mindestbesetzung zu unterschreiten.

Beide Transaktionen lesen also dieselbe Ausgangssituation, treffen jeweils für sich genommen eine plausible, regelkonforme Entscheidung und schreiben anschließend jeweils eine andere Zeile, nämlich ihre eigene Abmeldung. Da beide Zeilen verschieden sind, greift die First-Committer-Wins-Regel nicht, beide Commits gelingen, und am Ende sind beide Personen abgemeldet, obwohl die Geschäftsregel mindestens eine im Dienst verlangt.


-- Transaktion A (Aerztin A meldet sich krank)
BEGIN;
SELECT count(*) FROM dienst WHERE aktiv = true;  -- liefert 2
UPDATE dienst SET aktiv = false WHERE person = 'Aerztin A';
COMMIT;

-- Transaktion B (Arzt B meldet sich krank), zeitgleich gestartet
BEGIN;
SELECT count(*) FROM dienst WHERE aktiv = true;  -- liefert ebenfalls 2
UPDATE dienst SET aktiv = false WHERE person = 'Arzt B';
COMMIT;
-- Ergebnis: 0 Personen im Dienst, Geschäftsregel verletzt

4. Warum Write Skew unter reiner Snapshot Isolation überhaupt möglich ist

Der First-Committer-Wins-Mechanismus von Snapshot Isolation erkennt ausschließlich direkte Schreibkonflikte auf derselben physischen Zeile. Im Bereitschaftsdienst-Beispiel schreibt jede Transaktion jedoch eine andere Zeile, die Lesekonsistenz-Verletzung entsteht nicht durch einen Konflikt beim Schreiben, sondern durch die logische Abhängigkeit zwischen dem, was gelesen wurde, und dem, was später von einer anderen Transaktion geschrieben wird.

Diese Art von Abhängigkeit nennt sich in der Literatur eine rw-Antidependency: Transaktion A liest eine Menge an Zeilen, die von Transaktion B anschließend verändert wird, und umgekehrt liest Transaktion B eine Menge, die von Transaktion A verändert wird. Erst wenn beide Richtungen dieser Abhängigkeit gleichzeitig auftreten, entsteht die klassische Write-Skew-Anomalie, und genau dieses Muster kann ein reiner Zeilen-Konflikt-Check per Definition nicht erkennen.

5. Serializable Snapshot Isolation: die Grundidee

Serializable Snapshot Isolation baut auf demselben Snapshot-Mechanismus auf, ergänzt ihn aber um eine zusätzliche Laufzeitüberwachung, die genau nach den oben beschriebenen rw-Antidependencies zwischen gleichzeitig laufenden Transaktionen sucht. Erkennt die Datenbank ein Muster, das potenziell zu einer nicht-serialisierbaren Ausführung führen würde, bricht sie eine der beteiligten Transaktionen gezielt mit einem Serialization-Failure-Fehler ab, statt beide committen zu lassen.

Der entscheidende konzeptionelle Unterschied zu klassischem, sperrenbasiertem Serializable ist, dass SSI optimistisch bleibt: Es werden weiterhin keine Sperren für Lesezugriffe gehalten, sondern lediglich Abhängigkeiten mitprotokolliert und im Konfliktfall nachträglich aufgelöst, was unter geringer bis mittlerer Konfliktrate deutlich weniger Overhead erzeugt als durchgängiges pessimistisches Sperren.

6. Implementierungen: PostgreSQL SERIALIZABLE im Vergleich zu klassischem Locking

PostgreSQL implementiert Serializable Snapshot Isolation seit Version 9.1 direkt hinter dem Isolationslevel SERIALIZABLE, wählbar über eine einfache Transaktionseinstellung, ohne dass sich am eigentlichen SQL etwas ändert. Andere Systeme, etwa klassische, ältere Implementierungen von SERIALIZABLE in verschiedenen Datenbanken, setzen stattdessen auf strikte Zwei-Phasen-Sperrverfahren, bei denen Lesezugriffe echte Sperren belegen, die andere Transaktionen aktiv blockieren, statt lediglich Konflikte im Nachhinein zu erkennen.

Der praktische Unterschied zeigt sich vor allem unter Last: Sperrenbasiertes Serializable kann bei vielen gleichzeitigen Lesezugriffen auf überlappende Datenbereiche zu spürbarer Blockierung und im schlimmsten Fall zu Deadlocks führen, während SSI Lesezugriffe grundsätzlich nie blockiert, dafür aber im Konfliktfall eine bereits laufende Transaktion mit einem Abbruch zurückweist, den die Anwendung durch einen erneuten Versuch auffangen muss.

7. Das Bereitschaftsdienst-Beispiel unter SSI erneut durchgespielt

Unter SERIALIZABLE in PostgreSQL laufen beide Transaktionen aus dem Beispiel oben zunächst identisch ab: Beide lesen den Zählwert 2, beide entscheiden sich für die Abmeldung. Beim Versuch, als zweite Transaktion zu committen, erkennt PostgreSQL jedoch die rw-Antidependency zwischen beiden Transaktionen und lehnt diesen Commit mit einer expliziten Serialization-Failure-Fehlermeldung ab, während die erste Transaktion normal committet.

Die Anwendung muss auf diesen Fehler vorbereitet sein und die betroffene Transaktion erneut ausführen. Beim zweiten Versuch liest die wiederholte Transaktion dann den bereits reduzierten Zählwert von 1 und lehnt die Abmeldung korrekt selbst ab, wodurch die Geschäftsregel der Mindestbesetzung tatsächlich eingehalten bleibt, ganz ohne dass eine explizite Sperre auf die Zähltabelle nötig gewesen wäre.


BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT count(*) FROM dienst WHERE aktiv = true;
UPDATE dienst SET aktiv = false WHERE person = 'Aerztin A';
COMMIT;
-- Die zweite, parallele Transaktion erhält beim COMMIT:
-- ERROR: could not serialize access due to read/write dependencies
-- Anwendung muss die Transaktion mit Retry-Logik erneut ausführen

8. Die Kosten von SSI: Overhead und erhöhte Abbruchrate

SSI ist nicht kostenlos: Die Datenbank muss für jede Transaktion mitverfolgen, welche Zeilenmengen gelesen und geschrieben wurden, um mögliche rw-Antidependencies überhaupt erkennen zu können, was zusätzlichen Speicher- und Rechenaufwand gegenüber reiner Snapshot Isolation bedeutet. Bei Workloads mit sehr vielen, stark konkurrierenden Transaktionen auf überlappenden Datenbereichen steigt außerdem die Abbruchrate durch Serialization Failures spürbar.

Jede Anwendung, die SERIALIZABLE einsetzt, muss deshalb zwingend eine Retry-Logik für genau diesen Fehlerfall implementieren, üblicherweise mit einer begrenzten Anzahl an Wiederholungsversuchen und einem kurzen, zufälligen Backoff dazwischen, um wiederholte Kollisionen zwischen denselben Transaktionen unwahrscheinlicher zu machen.

9. Praxisempfehlung: wann Snapshot Isolation reicht und wann SSI nötig ist

Reine Snapshot Isolation genügt für die überwiegende Mehrheit der Anwendungsfälle, insbesondere wenn Geschäftsregeln sich stets auf eine einzelne Zeile beziehen lassen, etwa Kontostände oder Lagerbestände, bei denen der First-Committer-Wins-Mechanismus Konflikte zuverlässig erkennt. Für solche Fälle bietet SSI keinen zusätzlichen Nutzen, verursacht aber trotzdem den zusätzlichen Overhead der Abhängigkeitsverfolgung.

SSI wird dann relevant, wenn eine Geschäftsregel sich über mehrere, voneinander unabhängige Zeilen erstreckt und mehrere gleichzeitige Transaktionen jeweils für sich genommen konsistente, aber gemeinsam widersprüchliche Entscheidungen treffen können, wie im Bereitschaftsdienst-Beispiel. Kapazitätsgrenzen, gegenseitig ausschließende Zustände über mehrere Entitäten hinweg und ähnliche Constraint-artige Regeln sind typische Kandidaten, bei denen sich der Umstieg auf SERIALIZABLE trotz des Mehraufwands lohnt.

Anomalie Read Committed Snapshot Isolation Serializable Snapshot Isolation
Dirty Read Verhindert Verhindert Verhindert
Non-repeatable Read Möglich Verhindert Verhindert
Phantom Read Möglich Weitgehend verhindert Verhindert
Write Skew Möglich Möglich Verhindert
Overhead gegenüber Read Committed Keiner Moderat Höher, plus Abbruchrisiko

Mironsoft

Datenbank-Optimierung, Query-Tuning und Migrationen

SQL-Abfragen, die bei Wachstum immer langsamer werden?

Wir analysieren und optimieren SQL-Datenbanken unabhängig vom eingesetzten System, planen sichere Migrationen und Schema-Änderungen und bringen Teams Query-Optimierung praxisnah bei.

Query-Optimierung

Langsame Abfragen analysieren und mit Indizes und Explain-Plänen gezielt beschleunigen.

Migrations-Planung

Schema-Änderungen und Datenmigrationen sicher und ohne Downtime umsetzen.

Team-Schulung

SQL-Grundlagen und Performance-Denken praxisnah im Entwicklerteam verankern.

10. Zusammenfassung

Snapshot Isolation vs. SSI: das Wichtigste auf einen Blick

Snapshot Isolation

Vermeidet Dirty Reads, Non-repeatable Reads und die meisten Phantom Reads zuverlässig.

Write Skew

Zwei Transaktionen treffen unabhängig konsistente Entscheidungen, die gemeinsam eine Regel verletzen.

SSI

Erkennt rw-Antidependencies zur Laufzeit und bricht eine der Transaktionen gezielt ab.

PostgreSQL

Implementiert SSI seit Version 9.1 direkt hinter dem Isolationslevel SERIALIZABLE.

11. FAQ: Snapshot Isolation vs. SSI: das Wichtigste auf einen Blick

1Was ist der Kern von Snapshot Isolation?
Jede Transaktion sieht ab dem ersten Lesezugriff einen konsistenten Schnappschuss der Datenbank, unabhängig von parallel laufenden Schreibvorgängen anderer Transaktionen, bis sie selbst committet.
2Welche Anomalien verhindert Snapshot Isolation zuverlässig?
Dirty Reads, Non-repeatable Reads und weitgehend auch Phantom Reads werden vollständig vermieden, weil der Snapshot für die gesamte Transaktionsdauer stabil bleibt.
3Was ist eine Write-Skew-Anomalie?
Zwei Transaktionen lesen dieselbe Ausgangssituation, treffen jeweils für sich genommen eine plausible Entscheidung und schreiben unterschiedliche Zeilen, sodass am Ende gemeinsam eine Geschäftsregel verletzt wird, obwohl jede einzelne Transaktion korrekt gehandelt hat.
4Warum erkennt Snapshot Isolation Write Skew nicht?
Der First-Committer-Wins-Mechanismus prüft nur direkte Schreibkonflikte auf derselben Zeile. Bei Write Skew schreiben beide Transaktionen unterschiedliche Zeilen, weshalb kein direkter Konflikt erkannt wird.
5Was bedeutet rw-Antidependency?
Eine Transaktion liest eine Menge an Zeilen, die von einer anderen, gleichzeitig laufenden Transaktion anschließend verändert wird. Treten solche Abhängigkeiten in beide Richtungen gleichzeitig auf, entsteht das Muster hinter Write Skew.
6Wie löst Serializable Snapshot Isolation das Problem?
SSI überwacht zusätzlich zur Snapshot-Isolation zur Laufzeit rw-Antidependencies zwischen parallelen Transaktionen und bricht eine der beteiligten Transaktionen mit einem Serialization-Failure-Fehler ab, sobald ein gefährliches Muster erkannt wird.
7Seit wann unterstützt PostgreSQL Serializable Snapshot Isolation?
Seit Version 9.1, direkt hinter dem Isolationslevel SERIALIZABLE, ohne dass sich am SQL-Code selbst etwas ändert. Es genügt, dieses Isolationslevel für die Transaktion zu setzen.
8Muss eine Anwendung unter SSI Fehler explizit behandeln?
Ja, jede Anwendung, die SERIALIZABLE nutzt, muss eine Retry-Logik für Serialization-Failure-Fehler implementieren, üblicherweise mit begrenzter Wiederholungsanzahl und kurzem, zufälligem Backoff.
9Ist SSI langsamer als reine Snapshot Isolation?
SSI erzeugt zusätzlichen Overhead durch das Mitprotokollieren gelesener und geschriebener Zeilenmengen sowie eine höhere Abbruchrate bei stark konkurrierenden Workloads, bleibt aber grundsätzlich sperrfrei für Lesezugriffe.
10Wann lohnt sich der Umstieg von Snapshot Isolation auf SSI?
Vor allem bei Geschäftsregeln, die sich über mehrere unabhängige Zeilen erstrecken, etwa Kapazitätsgrenzen oder sich gegenseitig ausschließende Zustände, bei denen einzelne Transaktionen für sich genommen korrekt, gemeinsam aber widersprüchlich handeln können.