CodeGym /Kurse /SQL SELF /Beispiel für den Einsatz von Transaktionen in echten Szen...

Beispiel für den Einsatz von Transaktionen in echten Szenarien

SQL SELF
Level 39 , Lektion 3
Verfügbar

Manchmal erinnern Transaktionen an Charaktere aus Superheldenfilmen. Sie retten unsere Datenbanken vor Katastrophen bei Ausfällen, Fehlern oder Störungen. Wenn du an einer Aufgabe arbeitest, die mehrere Operationen erfordert, die nicht getrennt werden dürfen, sorgen Transaktionen dafür, dass alles als Einheit ausgeführt wird. Lass uns anschauen, wie das am Beispiel der Zahlungsabwicklung funktioniert.

Zahlungsabwicklung

Stell dir die klassische Situation vor: Du hast zwei Bankkonten und möchtest Geld von einem auf das andere überweisen. Das ist keine "One-Click"-Operation. Du musst sicherstellen, dass das Geld korrekt vom einen Konto abgebucht und dem anderen gutgeschrieben wird. Jeder Fehler kann zur Katastrophe führen: Entweder bleiben beide Konten unverändert oder das Gleichgewicht wird gestört (zum Beispiel verschwindet Geld oder taucht "aus dem Nichts" auf).

Szenario: Geldüberweisung zwischen Konten

Hier ist unser Code. Lies ihn aufmerksam, als wäre es eine Nachricht aus einer weit entfernten Galaxie:

-- Transaktion starten
BEGIN;

-- Schritt 1. Geld vom Konto des Absenders abbuchen
UPDATE accounts
SET balance = balance - 100
WHERE account_id = 1;

-- Schritt 2. Geld auf das Konto des Empfängers gutschreiben
UPDATE accounts
SET balance = balance + 100
WHERE account_id = 2;

-- Alles lief gut? Dann Änderungen speichern!
COMMIT;

Was ist hier wichtig?

  • Wenn bei Schritt 1 oder Schritt 2 etwas schiefgeht (zum Beispiel ein Fehler in der Abfrage, zu wenig Guthaben), kann die Transaktion zurückgerollt werden mit ROLLBACK, und die Daten bleiben im Ursprungszustand.
  • COMMIT garantiert, dass die Änderungen nur übernommen werden, wenn ALLE Schritte erfolgreich sind.

Balance-Check hinzufügen

Und was, wenn der Absender nicht genug Geld für die Überweisung hat? Lass uns einen Balance-Check einbauen, damit er nicht versehentlich ins Minus rutscht.

-- Transaktion starten
BEGIN;

-- Aktuelles Guthaben des Absenders abfragen
DO $$
DECLARE
    current_balance NUMERIC;
BEGIN
    SELECT balance INTO current_balance FROM accounts WHERE account_id = 1;

    -- Prüfen, ob genug Geld da ist
    IF current_balance >= 100 THEN
        -- Wenn genug Geld da ist, Überweisung ausführen
        UPDATE accounts
        SET balance = balance - 100
        WHERE account_id = 1;

        UPDATE accounts
        SET balance = balance + 100
        WHERE account_id = 2;

        -- Änderungen festschreiben
        COMMIT;
    ELSE
        -- Wenn nicht genug Geld da ist, zurückrollen
        ROLLBACK;
        RAISE NOTICE 'Nicht genug Guthaben für die Überweisung!';
    END IF;
END $$;

Was ist hier schon spannender?

  • Wir nutzen einen PL/pgSQL-Block mit einer Bedingungsprüfung via IF. Wenn das Guthaben kleiner als der benötigte Betrag ist, wird die Transaktion abgelehnt und nichts geändert.
  • ROLLBACK macht Änderungen rückgängig, falls welche gemacht wurden (auch wenn hier noch nichts geändert wurde, ist das trotzdem guter Stil).
Wichtig!

Diese Lektion widmet sich echten Szenarien für den Einsatz von Transaktionen, deshalb habe ich hier ein Beispiel aus dem echten Leben genommen. Es enthält eine gespeicherte Prozedur und ist mit PL-SQL geschrieben. Ich denke, du hast schon genug Erfahrung, um zu verstehen, wie das hier funktioniert. In Zukunft kommen wir nochmal auf PL-SQL zurück und schauen uns noch viel komplexere Beispiele an.

Massen-Update von Daten in einer Transaktion

Eine Transaktion zu erstellen ist nicht nur für Geldüberweisungen praktisch. Angenommen, wir haben eine Datenbank eines Online-Shops, in der täglich Dutzende Bestellungen ihren Status ändern, zum Beispiel von "in Lieferung" zu "abgeschlossen". Wie aktualisiert man viele Datensätze auf einmal, sodass man im Fehlerfall alles zurückrollen kann? Natürlich mit einer Transaktion.

Schauen wir uns noch ein Szenario an: Status-Update von Bestellungen.

Hier ein Beispiel:

-- Transaktion starten
BEGIN;

-- Schritt 1. Bestellungen mit vergangenem Lieferdatum aktualisieren
UPDATE orders
SET status = 'abgeschlossen'
WHERE delivery_date < CURRENT_DATE;

-- Schritt 2. Über erfolgreichen Update informieren
RAISE NOTICE 'Alle Bestellstatus wurden erfolgreich aktualisiert.';

-- Änderungen übernehmen
COMMIT;

Und wenn etwas schiefgeht?

Es besteht immer die Möglichkeit eines Fehlers. Zum Beispiel hast du versehentlich die WHERE-Bedingung vergessen, und jetzt haben alle Bestellungen den Status abgeschlossen. Um solche Situationen zu vermeiden, ist es wichtig, die Transaktion zu beenden oder explizit zurückzurollen.

Hier ein Szenario mit Rollback:

-- Transaktion starten
BEGIN;

-- Schritt 1. Versuch, Bestellungen ohne Bedingung zu aktualisieren (oh nein, Fehler!)
UPDATE orders
SET status = 'abgeschlossen';

-- Transaktion wegen Fehler zurückrollen
ROLLBACK;

-- Jetzt sind die Bestellungen unverändert geblieben

Ein bisschen mehr "Flexibilität" mit SAVEPOINT

Man muss nicht immer die ganze Transaktion zurückrollen. Wenn dein Szenario aus mehreren Schritten besteht, willst du vielleicht nur einen Teil zurückrollen. Hier hilft SAVEPOINT.

Jetzt unser Szenario: Mehrere Schritte bearbeiten mit der Möglichkeit, einen davon zurückzurollen.

Stell dir vor, du bearbeitest eine Bestellung in mehreren Schritten: Artikel vom Lager abbuchen, Bestellstatus aktualisieren, Benachrichtigung an den Kunden schicken. Wenn die Benachrichtigung nicht erfolgreich gesendet wurde, willst du nur diesen Schritt zurückrollen, aber die Änderungen in der Datenbank behalten.

-- Transaktion starten
BEGIN;

-- Schritt 1. Artikel vom Lager abbuchen
UPDATE products
SET stock = stock - 1
WHERE product_id = 101;

-- Savepoint setzen
SAVEPOINT step1;

-- Schritt 2. Bestellstatus aktualisieren
UPDATE orders
SET status = 'versendet'
WHERE order_id = 202;

-- Versuch, Benachrichtigung an den Kunden zu senden
SAVEPOINT step2;
-- Ups, Fehler beim Benachrichtigen!
ROLLBACK TO SAVEPOINT step2;

-- Entscheiden, dass es sicher ist, die Transaktion abzuschließen
COMMIT;

Fazit

Transaktionen sind nicht nur ein technisches Werkzeug, sondern eine Garantie für die Integrität deiner Daten. Sie schützen vor dem "Domino-Effekt", bei dem ein Fehler das ganze System zerstören kann. Immer wenn du mehrere zusammenhängende Operationen ausführst, frag dich: "Was, wenn eine davon fehlschlägt?" Wenn die Antwort "Katastrophe" lautet, ist es Zeit für eine Transaktion. Denk dran: Lieber ein paar Minuten in eine Transaktion investieren als Stunden mit der Wiederherstellung von Daten nach einem Crash zu verbringen. Deine User (und deine Nerven) werden es dir danken!

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