Beschreiben von Isolationsstufen

Abgeschlossen

PostgreSQL verfügt über drei Ebenen der Transaktionsisolation, die drei Formen von Nebenläufigkeitskonflikten verhindern: Dirty Reads (Lesevorgänge ohne Commit), nicht wiederholbare Lesevorgänge und Phantomlesevorgänge.

Arten von Nebenläufigkeitskonflikten

Dirty Reads

Ein Dirty Read tritt auf, wenn eine Transaktion die aktualisierte Version von Daten liest, während diese von einer anderen Transaktion bearbeitet wird. Dieses Update wird jedoch nie committet.

Angenommen, auf einem Sparkonto erfolgt eine Transaktion, durch die der Saldo des Kontos unter Null fallen würde. Bevor die Transaktion committet wird, wird das Kontoguthaben überprüft und die Transaktion zurückgesetzt, da der Saldo von Sparkonten nicht unter Null liegen darf. Gleichzeitig wird ein Bericht ausgeführt, der das aktuelle Guthaben aller Sparkonten anzeigt. Wenn Dirty Reads erlaubt sind, würde der negative Saldo zurückgegeben werden, auch wenn er nie committet wird.

Nicht wiederholbare Lesevorgänge

Ein nicht wiederholbarer Lesevorgang tritt in folgendem Fall auf: Eine Transaktion liest Daten, eine andere Transaktion aktualisiert die Daten, und die erste Transaktion liest die Daten noch einmal, wobei sie die neuen Updates sieht.

Beispiel: Verbindung A startet eine Transaktion und liest die Kosten pro Einheit sowie die Anzahl der Einheiten für eine Bestellung. Die Kosten betragen 10, und die Anzahl der Einheiten ist 3. Dann startet Verbindung B eine andere Transaktion und aktualisiert die gleiche Bestellung, um die Kosten pro Einheit auf 12 festzulegen. In derselben Transaktion wie die ursprüngliche Abfrage berechnet Verbindung A die Gesamtkosten für die Bestellung. Wenn nicht wiederholbare Lesevorgänge erlaubt sind, gibt Verbindung A Kosten pro Einheit von 10, eine Anzahl der Einheiten von 3 und Gesamtkosten von 36 zurück, was keinen Sinn ergibt.

Phantomlesezugriffe

Ein Phantomlesevorgang tritt in folgendem Fall auf: Eine Transaktion liest Daten, eine andere Transaktion fügt den Daten eine oder mehrere neue Zeilen hinzu, und die erste Transaktion liest die Daten noch einmal, wobei sie die neuen Updates sieht.

Beispiel: Verbindung A startet eine Transaktion und zählt die Gesamtanzahl von Rechnungen pro Tag in Paris. Die Gesamtanzahl beträgt 1.100 Rechnungen für alle zehn Filialen in Paris. Dann startet Verbindung B eine weitere Transaktion und fügt eine neue Filiale in Paris mit 200 Rechnungen am Eröffnungstag hinzu. In der Transaktion von Verbindung A zählt das System jetzt die Anzahl von Filialen, um die Anzahl von Rechnungen pro Filiale zu berechnen. Verbindung A würde jetzt die 1.100 Transaktionen durch elf Filialen dividieren anstelle der ursprünglichen zehn, die beim Ausführen der Abfrage zum Ermitteln der Rechnungsanzahl vorhanden waren. Diese Berechnung gibt jetzt einen falschen Mittelwert von 100 zurück, obwohl die neue Filiale 200 Rechnungen hatte, die jedoch von der Transaktion von Verbindung A beim Berechnen des Mittelwerts nicht berücksichtigt wurden.

Isolationsgrade

Azure Database for PostgreSQL besitzt drei Transaktionsisolationsstufen: Read Committed, wiederholbarer Lesevorgang und serialisierbar. „Read Uncommitted“ ist in Azure Database for PostgreSQL nicht verfügbar.

Wie Isolationsstufen sich auf Nebenläufigkeitskonflikte auswirken:

Isolationsstufe Dirty Read Nicht wiederholbarer Lesevorgang Phantom Read
Read Uncommitted* Möglich Möglich Möglich
Read Committed Nicht möglich Möglich Möglich
Repeatable Read Nicht möglich Nicht möglich Möglich
Serialisierbar Nicht möglich Nicht möglich Nicht möglich

* In PostgreSQL nicht verfügbar

Die Standardisolationsstufe in Azure Database for PostgreSQL lautet„Read Committed“. „Read Committed“ eignet sich für die meisten Szenarios am besten, da Dirty Reads verhindert werden und eine gute Leistung geboten wird. Nicht wiederholbare Lesevorgänge und Phantomlesevorgänge können auftreten, jedoch nur, wenn mehrere SELECT-Anweisungen gleichzeitig die gleichen Daten abfragen.

Wiederholbare Lesevorgänge unterscheiden sich von Lesevorgängen mit Commit, da mehrere SELECT-Anweisungen innerhalb einer Transaktion dieselben Ergebnisse liefern würden, auch wenn eine andere Transaktion die Zeilen zwischen der Ausführung der beiden SELECT-Anweisungen der Transaktion aktualisiert hätte. Wenn eine andere Transaktion neue Zeilen einfügt, werden diese nicht in den Ergebnissen der zweiten SELECT-Anweisung angezeigt.

Die serialisierbare Isolationsstufe bietet die höchste Stufe der Transaktionsisolation und wird so ausgeführt, als ob verschiedene Transaktionen in Serie ablaufen, also eine nach der anderen. Der Nachteil serialisierbarer Isolationsstufen besteht darin, dass eine Transaktion, die Daten aktualisiert, von anderen Transaktionen blockiert werden kann. Die serialisierbare Transaktion muss warten, bis die blockierende Transaktion abgeschlossen ist, was sich auf die Leistung auswirkt.

Serialisierbare Transaktionen können außerdem keine Änderungen an Zeilen vornehmen, die während der serialisierbaren Transaktion von anderen Transaktionen geändert werden. Wenn diese Art von Konflikt auftritt, wird eine Fehlermeldung zurückgegeben. Daher ist es wichtig, über integrierte Wiederholungslogik in Anwendungen zu verfügen, wenn serialisierbare Transaktionen verwendet werden.

Um Transaktionsisolationsstufen zu aktualisieren, verwenden Sie den Befehl TRANSACTION ISOLATION LEVEL in einer Transaktion.

Zum Beispiel:

BEGIN TRANSACTION
TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT * FROM humanresources.department
COMMIT;