Eine Überweisung, halb ausgeführt
Nordwind Rad bezahlt den Reifenlieferanten: 400 Euro wandern von einem Konto auf ein anderes. Das Programm bucht zuerst 400 Euro vom Konto des Ladens ab. Gleich danach fällt der Server aus.
Das Geld hat ein Konto verlassen und das andere nie erreicht. Das darf einer Bank nicht passieren. Datenbanken haben dafür ein Werkzeug.
Am Ende dieser Lektion
Notiz
Ich kann erklären, warum eine Überweisung ganz oder gar nicht ausgeführt werden muss.
Schlüsselwörter
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Transaktion | Schreibvorgänge, die alle gelingen oder alle zurückgenommen werden | |
| BEGIN | eröffnet eine Transaktion | BEGIN; |
| COMMIT | macht alle Schreibvorgänge seit BEGIN endgültig | COMMIT; |
| ROLLBACK | nimmt alle Schreibvorgänge seit BEGIN zurück | ROLLBACK; |
| UPDATE | ändert bestehende Zeilen | |
| Kontostand | das Geld, das auf einem Konto liegt |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Eine Überweisung besteht aus zwei Schreibvorgängen
Bisher haben Ihre Abfragen gelesen. UPDATE schreibt: Es ändert bestehende Zeilen.
Eine Überweisung braucht zwei UPDATE. Das erste zieht Geld von einem Konto ab. Das zweite schreibt es dem anderen gut. Gelingt nur das erste, verschwindet das Geld. Gelingt nur das zweite, entsteht Geld aus dem Nichts. Beides ist ein schwerer Fehler.
BEGIN eröffnet, COMMIT bestätigt
BEGIN eröffnet eine Transaktion. Die Schreibvorgänge danach sind vorläufig und noch nicht endgültig.
COMMIT macht sie alle zugleich endgültig. Fällt der Server vor dem COMMIT aus, verwirft die Datenbank sie beim Neustart. Eine halbe Transaktion behält sie nie.
Probieren Sie es: eine bestätigte Überweisung
-- Eine Überweisung von 400 Euro in einer Transaktion.
BEGIN;
UPDATE konten SET kontostand = kontostand - 400 WHERE id = 1;
UPDATE konten SET kontostand = kontostand + 400 WHERE id = 2;
COMMIT;
SELECT * FROM konten;
Ein Beispiel Schritt für Schritt: die Kontostände
| Schritt | Konto 1 | Konto 2 | Summe |
|---|---|---|---|
| Vor BEGIN | 1200 | 300 | 1500 |
| Nach der Abbuchung | 800 | 300 | 1100 |
| Nach der Gutschrift | 800 | 700 | 1500 |
| Nach COMMIT | 800 | 700 | 1500 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
ROLLBACK nimmt alles zurück
Manchmal erkennt das Programm selbst ein Problem: zu wenig Geld, ein gesperrtes Konto. Dann schreibt es ROLLBACK.
Alle Schreibvorgänge seit BEGIN sind aufgehoben. Die Datenbank steht wieder genau wie vorher. Starten Sie den nächsten Block. Ersetzen Sie danach ROLLBACK durch COMMIT, um den Unterschied zu sehen.
Probieren Sie es: eine zurückgenommene Überweisung
-- Die Abbuchung ist geschehen, dann tritt ein Problem auf.
BEGIN;
UPDATE konten SET kontostand = kontostand - 400 WHERE id = 1;
-- Das Programm erkennt den Fehler und macht alles seit BEGIN rückgängig.
ROLLBACK;
SELECT * FROM konten;
-- Ersetzen Sie ROLLBACK durch COMMIT und starten Sie noch einmal. Wo sind die 400 Euro?
Ein häufiger Fehler
Warnung
Viele glauben, ein Fehler mitten im Ablauf mache alles von selbst rückgängig. Ohne Transaktion stimmt das nicht. Dann gilt jedes UPDATE sofort, wenn es ausgeführt ist. Gehören zwei Schreibvorgänge zusammen, setzen Sie sie zwischen BEGIN und COMMIT.
Dieselbe Regel in einem Programm
Auch in einer Anwendung gilt: alles oder nichts. Die einfachste Regel heißt: erst prüfen, dann schreiben.
In der nächsten Aufgabe bucht die Funktion ueberweisen zuerst ab und prüft danach den Kontostand. Das ist zu spät, denn die Abbuchung ist schon geschehen. Ändern Sie die Funktion so, dass eine Ablehnung nichts verändert.