- 1 Section
- 10 Lessons
- unbegrenzt
- Datenintegrität & Transaktionen10
- 1.1Integritätstypen
- 1.2Primary Key, Foreign Key, Constraints
- 1.3Referenzielle Integrität: ON DELETE, ON UPDATE
- 1.4Was sind Transaktionen?
- 1.5ACID-Eigenschaften
- 1.6Transaktions-Isolation und Anomalien
- 1.7COMMIT, ROLLBACK und SAVEPOINT
- 1.8Deadlocks: Entstehung und Vermeidung
- 1.9Datenbankindizes und Performance
- 1.10Aufgaben Datenintegrität
COMMIT, ROLLBACK und SAVEPOINT
Drei kleine Befehle steuern jede Transaktion: COMMIT, ROLLBACK und SAVEPOINT. Sie wurden bisher in jeder Lektion erwähnt – jetzt schauen wir sie systematisch an. Nach dieser Lektion solltest du dich nicht nur an die Syntax erinnern, sondern auch wissen wie das Zusammenspiel mit Autocommit, impliziten Commits und Savepoints in der Praxis funktioniert.
Der wichtigste Punkt zuerst: zwischen BEGIN und COMMIT/ROLLBACK sind alle Änderungen vorgemerkt, aber noch nicht endgültig. Erst COMMIT macht sie für alle anderen Sitzungen sichtbar und garantiert ihre Durability. ROLLBACK wirft alles weg – als wäre die Transaktion nie passiert.
1) Die drei Befehle im Detail
Die Syntax ist standardisiert und in allen relationalen DBMS gleich. Manche Varianten existieren – die Bedeutung ist aber überall identisch:
BEGIN;
BEGIN TRANSACTION;
START TRANSACTION;
-- Änderungen dauerhaft machen
COMMIT;
COMMIT WORK; -- Standardvariante, äquivalent
-- Änderungen verwerfen
ROLLBACK;
ROLLBACK WORK;
-- Markierung mitten in der Transaktion
SAVEPOINT name;
ROLLBACK TO SAVEPOINT name;
RELEASE SAVEPOINT name;
Jeder dieser Befehle hat eine klare Rolle. BEGIN öffnet eine Transaktion, COMMIT oder ROLLBACK schließt sie. Eine Transaktion ist immer mindestens zwischen einem öffnenden und einem schließenden Befehl eingerahmt. Was dazwischen passiert, ist Teil der Einheit.
2) COMMIT – der Punkt ohne Wiederkehr
Wenn du COMMIT ausführst, passieren mehrere Dinge gleichzeitig im DBMS – aus deiner Sicht aber atomar in einem Schritt:
- Alle Constraints werden final geprüft (deferred constraints, falls vorhanden). Wenn etwas fehlt, schlägt der COMMIT fehl und es kommt zu einem impliziten Rollback.
- Das Transaktionslog wird mit einem „committed"-Marker versehen und per
fsyncauf die Platte gezwungen. Erst dann ist die Durability garantiert. - Alle gehaltenen Sperren werden freigegeben – andere Transaktionen, die gewartet haben, können weiterlaufen.
- Die Änderungen werden für andere Sitzungen sichtbar (je nach Isolationsstufe).
- Die Sitzung kehrt in den Idle-Zustand zurück – die nächste Operation startet eine neue Transaktion.
Nach einem erfolgreichen COMMIT gibt es kein zurück mehr. Die Änderungen sind real. Wenn sie fachlich falsch waren, brauchst du eine neue Transaktion mit Gegenbuchung – ein „Korrektur-INSERT" oder „Korrektur-UPDATE". Daher: vor jedem COMMIT prüfen.
3) ROLLBACK – die Notbremse
ROLLBACK ist das Gegenteil von COMMIT: alle Änderungen seit dem letzten BEGIN werden zurückgenommen. Der Stand vor der Transaktion ist wiederhergestellt – als wäre nichts passiert. Das DBMS nutzt dafür die alten Werte aus dem Transaktionslog (siehe L4 zum Write-Ahead-Log).
ROLLBACK passiert in drei Situationen:
- Explizit: du rufst
ROLLBACKauf, weil etwas schiefging oder die Logik einen Abbruch verlangt. - Implizit durch Fehler: ein SQL-Befehl schlägt fehl (Constraint-Verletzung, Tippfehler im SQL, Deadlock). Je nach DBMS und Connection-Einstellung wird die ganze Transaktion abgebrochen oder nur der eine Befehl.
- Implizit durch Verbindungsabbruch: wenn die Datenbankverbindung geschlossen wird ohne COMMIT, rollt das DBMS die offene Transaktion zurück. Wichtig: kein Datenverlust durch vergessenes COMMIT, aber auch keine Speicherung von dem, was du vielleicht erwartet hast.
Auch beim Crash des Servers wird beim Neustart automatisch ROLLBACK aller offenen Transaktionen ausgeführt. Das ist Teil der Recovery-Logik aus dem Transaktionslog.
4) Interaktive Konsole – probier es aus
Klick durch eine simulierte SQL-Konsole. Beobachte wie der Saldo und der Transaktions-Status sich ändern:
BEGIN öffnest du eine mehrteilige Transaktion. Während sie offen ist, sind die Änderungen für andere Sitzungen je nach Isolationsstufe unsichtbar. ROLLBACK bringt alles auf den Stand vor BEGIN zurück.5) SAVEPOINT – Zwischenstände markieren
Manchmal willst du nicht die ganze Transaktion zurückrollen, sondern nur einen Teil. Stell dir vor: eine lange Import-Transaktion läuft, in Schritt 47 von 100 schlägt etwas fehl. Mit einem normalen ROLLBACK wären alle 46 vorherigen Schritte verloren. Mit einem Savepoint kannst du gezielt nur bis zu einem Punkt zurückgehen:
INSERT INTO kunden VALUES (1, 'Anna');
SAVEPOINT nach_kunde;
INSERT INTO bestellungen VALUES (...); -- schlägt fehl
ROLLBACK TO SAVEPOINT nach_kunde;
-- Anna bleibt drin, die fehlgeschlagene Bestellung ist weg
INSERT INTO bestellungen VALUES (...); -- zweiter Versuch mit korrigierten Daten
COMMIT;
Savepoints können geschachtelt werden – du kannst beliebig viele setzen, mit unterschiedlichen Namen. Sie liegen wie ein Stapel übereinander. Bei einem ROLLBACK zu einem Savepoint werden alle Savepoints die nach ihm gesetzt wurden automatisch verworfen.
SAVEPOINT name legt einen neuen ab. ROLLBACK TO SAVEPOINT name rollt alles bis dorthin zurück (alle späteren Savepoints werden mit verworfen). RELEASE SAVEPOINT name löscht einen Savepoint ohne Daten zu ändern – nur wenn du sicher bist, dass du nicht mehr zurück willst. Ein finaler COMMIT oder ROLLBACK verwirft alle Savepoints der Transaktion.6) Autocommit – die unsichtbare Standardeinstellung
In den meisten Datenbank-Clients ist eine Einstellung aktiv die viele Anfänger verwirrt: der Autocommit-Modus. Wenn er an ist (Default in den meisten Clients), wird jede einzelne Anweisung implizit in eine eigene Transaktion verpackt und sofort committed. Das ist praktisch für einzelne Befehle – kann aber bei Mehrschritt-Logik gefährlich werden.
BEGIN braucht es nur wenn du eine mehrteilige Transaktion willst. Vorsicht: ohne explizites BEGIN kannst du nichts rückgängig machen!COMMIT oder ROLLBACK rufen, sonst hängt sie ewig. Anwendungs-Frameworks setzen oft Autocommit aus.SELECT @@autocommit; in MySQL bzw. SHOW autocommit; verrät es dir.7) Implizite COMMITs – die heimtückischste Falle
Manche SQL-Befehle führen einen impliziten COMMIT aus, ohne dass du es bemerkst. Wenn du mitten in einer Transaktion einen dieser Befehle ausführst, wird die laufende Transaktion vorher committed, dann der DDL-Befehl ausgeführt, dann eine neue Transaktion gestartet. Beispiele in MySQL:
- DDL-Befehle:
CREATE TABLE,ALTER TABLE,DROP TABLE,CREATE INDEX,TRUNCATE TABLE– alle führen impliziten COMMIT aus. - Transaktionssteuerung:
BEGINmitten in einer offenen Transaktion committet die bisherige zuerst. - Verbindungs-Settings:
SET autocommit = 1oder Wechsel der Isolationsstufe können je nach DBMS implizit committen. - LOCK TABLES / UNLOCK TABLES committet implizit.
Praktische Konsequenz: vermische niemals DDL und DML in einer Transaktion. PostgreSQL ist hier eine löbliche Ausnahme – dort lassen sich auch DDL-Befehle innerhalb einer Transaktion rollbacken. In MySQL und Oracle nicht. Wenn du eine Migration schreibst, plane DDL und Daten-Manipulation getrennt.
8) Praktische Patterns
Vier typische Anwendungsmuster, die du im Code wiederfinden wirst:
BEGIN;
-- Operationen ...
COMMIT; -- bei Erfolg
ROLLBACK; -- bei Fehler
-- Pattern 2: Savepoint für teilweise Wiederholung
BEGIN;
-- Setup-Operationen ...
SAVEPOINT retry_point;
-- riskante Operation
-- bei Fehler: ROLLBACK TO SAVEPOINT retry_point + Retry
COMMIT;
-- Pattern 3: lange Read-Only Transaktion mit REPEATABLE READ
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
-- viele SELECTs für konsistenten Report
COMMIT; -- gibt MVCC-Snapshot frei
-- Pattern 4: Schleifen-Import mit Batch-COMMIT
BEGIN;
-- 1000 Inserts ...
COMMIT; -- alle 1000 zusammen schneller als 1000 einzelne Mini-TX
Pattern 4 ist eine häufige Performance-Falle anders herum: ohne explizite Transaktion ist jedes INSERT eine eigene Transaktion mit eigenem fsync. 1000 Inserts können 1000-mal langsamer sein als die gleichen 1000 Inserts in einer einzigen Transaktion. Massendaten immer batch-weise committen, typisch in Häppchen von 1.000 bis 10.000.
Zusammenfassung
Drei Befehle steuern jede Transaktion: BEGIN (öffnen), COMMIT (dauerhaft speichern), ROLLBACK (verwerfen). Hinzu kommt SAVEPOINT name für Markierungen innerhalb der Transaktion, gefolgt von ROLLBACK TO SAVEPOINT name für partielles Zurückrollen und RELEASE SAVEPOINT name zum Verwerfen ohne Datenänderung. Das DBMS arbeitet meist im Autocommit-Modus – jede einzelne Anweisung ist ihre eigene Mini-Transaktion. Erst explizites BEGIN öffnet eine mehrteilige Transaktion. Implizite COMMITs sind eine wichtige Falle: DDL-Befehle (CREATE, ALTER, DROP, TRUNCATE) committen die laufende Transaktion automatisch – DDL und DML nie mischen (außer in PostgreSQL). Performance-Tipp: viele kleine Operationen in einer expliziten Transaktion bündeln statt 1000 Mini-Transaktionen. Verbindungsabbruch ohne COMMIT führt zu automatischem ROLLBACK – kein Datenverlust, aber auch keine stille Speicherung.
