PostgreSQL verfügt über solide, bewährte Funktionen, mit denen Sie genau definieren können, was passieren soll, wenn mehrere Clients versuchen, dieselben Daten gleichzeitig zu aktualisieren. Eine davon ist die Isolationsstufe von Transaktionen.
Lesen Sie weiter, um mehr darüber zu erfahren, wie die Transaktionsisolation in PostgreSQL funktioniert.
Transaktionen und Isolationsstufe
Transaktionen sind die grundlegende Möglichkeit, Daten in einem RDBMS zu mutieren. Moderne RDBMS ermöglichen die gleichzeitige Ausführung von mehr als einer Transaktion und verfügen daher über eine Vielzahl von Tools – einige Standard-, andere RDBMS-spezifische – für Anwendungsentwickler, mit denen sie angeben können, wie ihre Transaktionen mit anderen Transaktionen interagieren sollen oder nicht.
Transaktionsisolationsstufen und pessimistische Sperren sind zwei solcher Tools. Obwohl diese für die Datenintegrität und -leistung erforderlich sind, sind sie leider nicht intuitiv zu verstehen oder zu verwenden.
Die Isolationsstufe einer Transaktion kann in PostgreSQL eine der folgenden sein:
- Zugesagt lesen
- Wiederholbarer Lesevorgang
- Serialisierbar
Bei jeder Transaktion ist ihre Isolationsstufe bei ihrer Erstellung auf eine dieser Stufen eingestellt. Die Standardstufe ist „Read Committed“.
Beachten Sie, dass der SQL-Standard auch „Read Uncommitted“ definiert, was in Postgres nicht unterstützt wird. Sie müssen die nächste, höhere Ebene von „Read Committed“ verwenden.
Mal sehen, was diese Ebenen bedeuten.
Lesen bestätigt
Was passiert, wenn eine (nicht abgeschlossene) Transaktion Zeilen in eine Tabelle einfügt und die andere (ebenfalls nicht abgeschlossene) Transaktion versucht, alle Zeilen in der Tabelle zu lesen? Wenn die zweite Transaktion die von der ersten eingefügten Zeilen sehen kann, wird diese Leseoperation als dirty read bezeichnet – weil die erste Transaktion einen Rollback durchführen kann und die zweite Transaktion „Phantom“-Zeilen gelesen hätte, die nie existierten.
Der Lesebefehl Die Isolationsstufe garantiert, dass niemals Dirty Reads passieren. Hier ist ein Beispiel:
Wie Sie sehen können, konnte die zweite Transaktion die noch nicht festgeschriebenen Daten der ersten Transaktion nicht lesen. In PostgreSQL ist es nicht möglich, die Isolationsstufe unter diese Stufe zu senken, sodass Dirty Reads zulässig sind.
Wiederholbarer Lesevorgang
Ein weiteres Problem sind nicht wiederholbare Lesevorgänge. Diese treten auf, wenn eine Transaktion eine Zeile liest und etwas später erneut liest, aber ein anderes Ergebnis erhält, weil die Zeile zwischenzeitlich durch eine andere Transaktion aktualisiert wurde. Der Lesevorgang ist nicht wiederholbar geworden , wie in diesem Beispiel gezeigt:
Um dieses Problem zu beheben, setzen Sie die Isolationsstufe der Transaktion auf „repeatableread“. PostgreSQL stellt dann sicher, dass der zweite (oder jeder) Lesevorgang dasselbe Ergebnis wie der erste Lesevorgang zurückgibt. Hier ist das gleiche Szenario auf der aktualisierten Isolationsstufe:
Beachten Sie, dass die Isolationsstufe zusammen mit der BEGIN-Anweisung angegeben wurde. Es ist auch möglich, dies auf Verbindungsebene (als Verbindungsparameter), als Konfigurationsparameter (default_transaction_isolation
) anzugeben ) und mit der Anweisung SET TRANSACTION.
Serialisierbar
Die nächste Isolationsstufe befasst sich mit dem Problem verlorener Updates . Aktualisierungen, die in einer Transaktion durchgeführt werden, können „verloren gehen“ oder von einer anderen Transaktion überschrieben werden, die zufällig gleichzeitig ausgeführt wird, wie hier gezeigt:
Hier blockiert das UPDATE der zweiten Transaktion, da PostgreSQL eine Sperre setzt, um ein weiteres Update zu verhindern, bis die erste Transaktion abgeschlossen ist. Allerdings geht die Änderung der ersten Transaktion verloren, weil die zweite die Zeile „überschrieben“ hat.
Wenn diese Art von Verhalten nicht akzeptabel ist, können Sie die Isolationsstufe auf serialisierbar aktualisieren:
Auf dieser Ebene schlägt die Festschreibung der zweiten Transaktion fehl. Die Handlungen der zweiten Transaktion basierten auf Tatsachen, die zum Zeitpunkt der Übergabe ungültig wurden.
Die Serialisierung bietet zwar die höchste Sicherheitsstufe, bedeutet aber auch, dass die Anwendung solche Commit-Fehler erkennen und die gesamte Transaktion wiederholen muss.