CodeGym /Kurse /SQL SELF /Verwendung von SAVEPOINT zur Steuerung von ...

Verwendung von SAVEPOINT zur Steuerung von teilweisen Rollbacks in Transaktionen

SQL SELF
Level 39 , Lektion 2
Verfügbar

Stell dir vor, du schreibst ein Buch. Aber hey, nicht immer läuft alles nach Plan. Manchmal schreibst du ein ganzes Kapitel, aber beim Durchlesen merkst du, dass der fünfte Absatz echt mies geworden ist. Was machst du? Du schmeißt doch nicht das ganze Kapitel in den Müll, oder? Stattdessen bearbeitest du nur die Stellen, die dir nicht gefallen.

So ähnlich funktioniert SAVEPOINT in PostgreSQL. Damit kannst du:

  1. Speicherpunkte innerhalb einer Transaktion setzen – wie Lesezeichen im Buch.
  2. Zu diesen Punkten zurückspringen, um nur einen Teil der Aktionen rückgängig zu machen, ohne die ganze Transaktion zu verlieren.
  3. Mit den restlichen Daten weitermachen, ohne alles von vorne zu starten.

Grundlegende Syntax von SAVEPOINT

Die Kommandos rund um SAVEPOINT sind ziemlich simpel. Hier das Basis-Set:

Speicherpunkt setzen (SAVEPOINT):

SAVEPOINT savepoint_name;

Das ist so, als würdest du sagen: "Lass uns diese Stelle merken, falls wir später zurückspringen müssen."

Zurückspringen zu einem Speicherpunkt (ROLLBACK TO SAVEPOINT):
ROLLBACK TO SAVEPOINT savepoint_name;

Wenn was schiefgeht, springst du zum angegebenen SAVEPOINT zurück und machst alle Änderungen seitdem rückgängig.

Speicherpunkt löschen (RELEASE SAVEPOINT):
RELEASE SAVEPOINT savepoint_name;

Damit löschst du das "Lesezeichen". Danach kannst du nicht mehr zu diesem Punkt zurückspringen.

Einfaches Beispiel: Einkauf im Online-Shop

Stell dir vor, wir betreiben einen Online-Shop. Ein Kunde legt mehrere Produkte in den Warenkorb, und wir wollen eine Transaktion ausführen, die die Bestellung abschließt und die Lagerbestände anpasst. Wenn aber ein Schritt fehlschlägt, wollen wir nur einen Teil der Transaktion zurückrollen, nicht alles.

BEGIN;

-- Schritt 1: Reserviere das Produkt "SQL-Buch"
UPDATE inventory SET stock = stock - 1 WHERE product_id = 101;

-- Speicherpunkt setzen
SAVEPOINT buch_reserviert;

-- Schritt 2: Reserviere das Produkt "PostgreSQL-Tasse"
UPDATE inventory SET stock = stock - 1 WHERE product_id = 102;

-- Ups, es gibt keine Tassen mehr im Lager!
ROLLBACK TO SAVEPOINT buch_reserviert;

-- Änderungen nur fürs Buch übernehmen
COMMIT;

Was passiert in diesem Beispiel?

  1. Wir starten die Transaktion mit BEGIN.
  2. Nach der Reservierung des Buchs setzen wir den Speicherpunkt buch_reserviert. Das ist unser erster "Checkpoint".
  3. Wir versuchen, die Tasse zu reservieren, aber es gibt einen Fehler (zum Beispiel ist das Produkt nicht mehr auf Lager).
  4. Wir springen zurück zum Speicherpunkt buch_reserviert, um nur die Änderungen für die Tasse rückgängig zu machen.
  5. Am Ende übernehmen wir die Änderungen fürs Buch mit COMMIT.

Komplexeres Beispiel: Mehrstufige Datenverarbeitung

Jetzt stell dir vor, du arbeitest mit einem Order-Management-System, wo du mehrere Tabellen updaten musst: orders (Bestellungen), inventory (Lagerbestand) und billing (Rechnungen). Wenn irgendwo was schiefgeht, willst du nicht den Fortschritt in den anderen Tabellen verlieren. Genau hier hilft SAVEPOINT.

BEGIN;

-- Schritt 1: Neue Bestellung anlegen
INSERT INTO orders (order_id, customer_id, status) VALUES (1, 123, 'offen');
SAVEPOINT nach_bestellung_erstellt;

-- Schritt 2: Lagerbestand aktualisieren
UPDATE inventory SET stock = stock - 2 WHERE product_id = 101;
SAVEPOINT nach_lager_aktualisiert;

-- Schritt 3: Bezahlung durchführen
INSERT INTO billing (order_id, amount, status) VALUES (1, 100, 'bezahlt');

-- Ups, Fehler: Kreditkarte abgelehnt!
ROLLBACK TO SAVEPOINT nach_lager_aktualisiert;

-- Wir sind zurück nach dem Lager-Update, aber die Bestellung bleibt auf "offen".
UPDATE orders SET status = 'fehlgeschlagen' WHERE order_id = 1;

COMMIT;

Beachte, wie wir mit SAVEPOINT die Transaktion in logische Schritte aufteilen und zum richtigen Punkt zurückspringen, um einen Teil der Änderungen zu behalten.

Nützliche Tipps für SAVEPOINT

  • Verwende sprechende Namen für Speicherpunkte. Im Beispiel oben ist nach_bestellung_erstellt viel aussagekräftiger als einfach schritt1.
  • Verschachtelte Speicherpunkte funktionieren: Du kannst SAVEPOINT sogar innerhalb eines Rollbacks zu einem anderen Punkt setzen.
  • Gib Ressourcen frei, indem du nicht mehr benötigte Speicherpunkte mit RELEASE SAVEPOINT löschst. Das kann die Performance verbessern, vor allem bei großen Transaktionen.

Echte Anwendungsszenarien

Bearbeitung von Banktransaktionen: Zum Beispiel, wenn du einen Betrag zwischen mehreren Konten überweist, kannst du zu einem bestimmten Schritt zurückspringen, falls eine Überweisung fehlschlägt.

Import von Daten aus Dateien: Wenn du eine große CSV-Datei importierst, kannst du jede Zeile prüfen und nur fehlerhafte Daten zurückrollen, während die erfolgreichen erhalten bleiben.

Massen-Update von Datensätzen: Wenn du ein komplexes SQL-Skript hast, das tausende Zeilen aktualisiert, kannst du mit SAVEPOINT zu einem früheren Schritt zurückspringen, falls in der Mitte ein Fehler auftritt.

Typische Fehler und Fallen

Manchmal kann die Verwendung von SAVEPOINT zu unerwarteten Ergebnissen führen, wenn du nicht genau weißt, wie sie funktionieren. Zum Beispiel:

  • Wenn du vergisst, zu einem Speicherpunkt zurückzuspringen oder ihn zu löschen, kannst du Situationen schaffen, in denen Ressourcen bis zum Ende der Transaktion blockiert bleiben.
  • SAVEPOINT kann keine Aktionen rückgängig machen, die vor dem Setzen des Speicherpunkts passiert sind. Zum Beispiel können Daten, die schon mit COMMIT gespeichert wurden, nicht mehr zurückgerollt werden.

Jetzt kannst du sicher mit Transaktionen experimentieren und Speicherpunkte genau da setzen, wo du sie brauchst. Es kommt noch mehr SQL-Praxis auf dich zu – mach dich bereit für die nächsten Abenteuer!

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION