Transaktionen
Lerne Transaktionen: Wie du mehrere SQL-Befehle als eine Einheit ausführst und bei Fehlern alles rückgängig machst.
Stell dir vor, du ueberweist Geld von einem Konto auf ein anderes. Der Betrag wird von deinem Konto abgebucht, aber bevor er gutgeschrieben wird, stuerzt das System ab. Ohne Transaktionen waere das Geld einfach weg! Transaktionen sorgen dafuer, dass so etwas nicht passiert.
Was sind Transaktionen?
Eine Transaktion ist eine Gruppe von SQL-Befehlen, die als eine einzige Einheit ausgefuehrt werden. Entweder werden alle Befehle ausgefuehrt oder keiner.
-- Transaktion starten
BEGIN;
-- Mehrere Befehle ausfuehren
UPDATE konten SET saldo = saldo - 100 WHERE id = 1;
UPDATE konten SET saldo = saldo + 100 WHERE id = 2;
-- Alles bestaetigen
COMMIT;
Wenn zwischen den beiden UPDATEs etwas schiefgeht, werden beide Aenderungen rueckgaengig gemacht.
ACID - Die vier Garantien
Transaktionen bieten vier wichtige Garantien, bekannt als ACID:
| Eigenschaft | Bedeutung | Beispiel |
|---|---|---|
| Atomicity | Alles oder nichts | Ueberweisung: Abheben UND Einzahlen, oder keins von beiden |
| Consistency | Daten bleiben konsistent | Kontosumme bleibt gleich |
| Isolation | Transaktionen stoeren sich nicht | Zwei gleichzeitige Ueberweisungen |
| Durability | Bestaetigt = dauerhaft | Nach COMMIT sind die Daten sicher |
BEGIN, COMMIT und ROLLBACK
BEGIN - Transaktion starten
BEGIN;
-- oder in manchen Datenbanken:
BEGIN TRANSACTION;
-- oder:
START TRANSACTION; -- PostgreSQL
COMMIT - Aenderungen bestaetigen
BEGIN;
INSERT INTO kunden (id, name, email, stadt)
VALUES (10, 'Test Kunde', 'test@example.com', 'Berlin');
-- Pruefen, ob alles stimmt
SELECT * FROM kunden WHERE id = 10;
-- Alles gut? Bestaetigen!
COMMIT;
ROLLBACK - Aenderungen rueckgaengig machen
BEGIN;
DELETE FROM bestellungen WHERE status = 'abgeschlossen';
-- Oh nein, das wollte ich nicht!
ROLLBACK;
-- Alle Bestellungen sind noch da!
Praktisches Beispiel: Bestellung aufgeben
Eine neue Bestellung besteht aus mehreren Schritten, die alle zusammengehoeren:
BEGIN;
-- 1. Bestellung erstellen
INSERT INTO bestellungen (id, kunden_id, bestelldatum, betrag, status)
VALUES (6, 2, CURRENT_DATE, 69.98, 'offen');
-- 2. Bestellpositionen hinzufuegen
INSERT INTO bestellpositionen (id, bestell_id, produkt_id, menge, einzelpreis)
VALUES (10, 6, 1, 2, 19.99);
INSERT INTO bestellpositionen (id, bestell_id, produkt_id, menge, einzelpreis)
VALUES (11, 6, 5, 2, 14.99);
-- 3. Lagerbestand reduzieren
UPDATE produkte SET lagerbestand = lagerbestand - 2 WHERE id = 1;
UPDATE produkte SET lagerbestand = lagerbestand - 2 WHERE id = 5;
-- Alles hat geklappt? Bestaetigen!
COMMIT;
Wenn bei Schritt 3 ein Fehler auftritt (z.B. nicht genug Lagerbestand), wird mit ROLLBACK alles rueckgaengig gemacht - auch die Bestellung und die Positionen.
Fehlerbehandlung
Manuelle Fehlerbehandlung
BEGIN;
-- Aenderungen vornehmen
UPDATE produkte SET preis = preis * 1.1 WHERE kategorie = 'Kleidung';
-- Pruefen
SELECT name, preis FROM produkte WHERE kategorie = 'Kleidung';
-- Entscheidung:
-- Wenn alles gut aussieht:
COMMIT;
-- Wenn nicht:
-- ROLLBACK;
Automatisches Rollback bei Fehlern
In den meisten Datenbanken wird eine Transaktion automatisch zurueckgerollt, wenn ein SQL-Fehler auftritt:
BEGIN;
INSERT INTO kunden (id, name, email, stadt)
VALUES (10, 'Neuer Kunde', 'neu@example.com', 'Berlin');
-- Dieser Befehl erzeugt einen Fehler (Duplikat-ID):
INSERT INTO kunden (id, name, email, stadt)
VALUES (10, 'Noch einer', 'noch@example.com', 'Hamburg');
-- FEHLER! -> Transaktion ist in einem Fehlerzustand
ROLLBACK; -- Muss explizit aufgerufen werden
-- Beide INSERTs sind rueckgaengig gemacht
SAVEPOINT - Teilweises Rollback
Mit SAVEPOINTs kannst du innerhalb einer Transaktion Zwischenstationen setzen:
BEGIN;
-- Kunden anlegen
INSERT INTO kunden (id, name, email, stadt)
VALUES (10, 'Kunde A', 'a@example.com', 'Berlin');
SAVEPOINT punkt1;
-- Bestellung anlegen
INSERT INTO bestellungen (id, kunden_id, betrag, status)
VALUES (6, 10, 99.99, 'offen');
SAVEPOINT punkt2;
-- Oops, die Bestellung war falsch
ROLLBACK TO punkt2;
-- Die Bestellung ist weg, aber Kunde A ist noch da!
-- Korrekte Bestellung anlegen
INSERT INTO bestellungen (id, kunden_id, betrag, status)
VALUES (6, 10, 49.99, 'offen');
COMMIT;
-- Kunde A und die korrekte Bestellung sind gespeichert
Isolation Levels
Wenn mehrere Benutzer gleichzeitig auf die Datenbank zugreifen, bestimmt der Isolation Level, wie Transaktionen voneinander isoliert sind:
| Level | Beschreibung | Sicherheit |
|---|---|---|
| READ UNCOMMITTED | Kann unverstaetigte Aenderungen lesen | Niedrig |
| READ COMMITTED | Liest nur bestaetigte Aenderungen | Mittel |
| REPEATABLE READ | Gleiche Abfrage liefert gleiche Ergebnisse | Hoch |
| SERIALIZABLE | Vollstaendige Isolation | Hoechst |
-- PostgreSQL: Isolation Level setzen
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;
-- Hier die Abfragen
COMMIT;
Fuer den Anfang ist der Standard (READ COMMITTED in PostgreSQL) voellig ausreichend.
Autocommit
Standardmaessig wird in den meisten Datenbanken jeder einzelne SQL-Befehl automatisch als eigene Transaktion behandelt (Autocommit):
-- Diese drei Befehle sind drei separate Transaktionen:
INSERT INTO kunden (id, name) VALUES (11, 'A'); -- automatisch COMMIT
INSERT INTO kunden (id, name) VALUES (12, 'B'); -- automatisch COMMIT
INSERT INTO kunden (id, name) VALUES (13, 'C'); -- automatisch COMMIT
Nur wenn du explizit BEGIN schreibst, werden mehrere Befehle zu einer Transaktion zusammengefasst.
Praxisbeispiele
Sichere Datenmigration
BEGIN;
-- Daten in Archiv-Tabelle kopieren
INSERT INTO bestellungen_archiv
SELECT * FROM bestellungen
WHERE status = 'abgeschlossen' AND bestelldatum < '2026-01-01';
-- Kopierte Daten pruefen
SELECT COUNT(*) FROM bestellungen_archiv;
-- Originaldaten loeschen
DELETE FROM bestellungen
WHERE status = 'abgeschlossen' AND bestelldatum < '2026-01-01';
-- Alles korrekt?
COMMIT;
-- Oder: ROLLBACK; falls etwas nicht stimmt
Preisaenderung mit Sicherung
BEGIN;
-- Aktuelle Preise merken (in einer temporaeren Tabelle)
CREATE TEMPORARY TABLE preise_backup AS
SELECT id, preis FROM produkte;
-- Preise aendern
UPDATE produkte SET preis = preis * 1.05;
-- Pruefen, ob die neuen Preise sinnvoll sind
SELECT p.name, pb.preis AS alter_preis, p.preis AS neuer_preis
FROM produkte p
JOIN preise_backup pb ON p.id = pb.id;
-- Entscheidung treffen
COMMIT; -- oder ROLLBACK;
Transaktionen in der Anwendungsentwicklung
In Programmiersprachen werden Transaktionen typischerweise so verwendet:
-- Pseudocode:
-- try {
-- BEGIN;
-- INSERT ...
-- UPDATE ...
-- DELETE ...
-- COMMIT;
-- } catch (error) {
-- ROLLBACK;
-- throw error;
-- }
Was kommt als Naechstes?
Im naechsten Tutorial lernst du CREATE TABLE kennen - damit erstellst du eigene Tabellen mit genau der Struktur, die du brauchst.
Zusammenfassung
- Transaktionen fassen mehrere SQL-Befehle zu einer Einheit zusammen
- BEGIN startet, COMMIT bestaetigt, ROLLBACK macht rueckgaengig
- ACID garantiert: Atomicity, Consistency, Isolation, Durability
- SAVEPOINTs ermoeglichen teilweises Rollback
- Ohne BEGIN arbeitet jeder Befehl im Autocommit-Modus
- Transaktionen sind unverzichtbar fuer Datenkonsistenz
Uebungen
- Einfach: Starte eine Transaktion, fuege einen neuen Kunden ein, pruefe mit SELECT, und fuehre dann ROLLBACK aus. Ist der Kunde noch da?
- Bestellung: Schreibe eine Transaktion, die eine neue Bestellung mit zwei Bestellpositionen anlegt und den Lagerbestand aktualisiert.
- SAVEPOINT: Erstelle eine Transaktion mit zwei INSERTs und einem SAVEPOINT dazwischen. Mache den zweiten INSERT mit ROLLBACK TO rueckgaengig.
- Fehlerszenario: Was passiert, wenn innerhalb einer Transaktion ein Constraint verletzt wird?
- Praxis: Schreibe eine Transaktion, die den Preis aller Produkte um 10% erhoeht, aber nur wenn kein Preis dabei ueber 200 Euro steigt.
-- Loesung zu Uebung 1:
BEGIN;
INSERT INTO kunden (id, name, email, stadt) VALUES (99, 'Test', 'test@test.com', 'Test');
SELECT * FROM kunden WHERE id = 99; -- Zeigt 'Test'
ROLLBACK;
SELECT * FROM kunden WHERE id = 99; -- Zeigt nichts - Rollback hat gewirkt!
Pro-Tipp: Mache es zur Gewohnheit, kritische Aenderungen (DELETE, UPDATE auf vielen Zeilen, Strukturaenderungen) immer in einer Transaktion auszufuehren. Selbst wenn du dir sicher bist - ein ROLLBACK kostet nichts und kann dich vor stundenlanger Wiederherstellungsarbeit bewahren.