A transaction bundles several writes into one all-or-nothing unit. Either every change lands, or none does — the database never gets stuck halfway through.
Where you meet it
- Bank transfers — debit one account, credit another, both or neither.
- Placing an order — deduct stock and create the order row together.
- Any multi-row update that must stay consistent: double-entry ledgers, seat booking, inventory.
What it does
It draws a boundary around a group of statements so the rest of the system sees them as a single step. From any other transaction's point of view it either happened completely or not at all — there is no visible in-between state.
Atomicity is free; isolation is the part you pay for — and your database hands you a weaker level than SERIALIZABLE by default.
How it works
You open with BEGIN, run your statements, then close with COMMIT (make it permanent) or ROLLBACK (throw it all away). The four guarantees are ACID: Atomicity — all statements land or none do. Consistency — rules and constraints stay true (the two balances still sum to the same total). Isolation — concurrent transactions don't see each other's half-done work. Durability — once committed, the change survives a crash.
The classic example is moving €30 from Ana to Ben:
BEGIN;
UPDATE accounts SET balance = balance - 30 WHERE name = 'Ana';
UPDATE accounts SET balance = balance + 30 WHERE name = 'Ben';
COMMIT;
If the credit fails after the debit ran, ROLLBACK undoes the debit too — the €30 never silently disappears.
Watch out
- Weak isolation lets anomalies through. A dirty read sees another transaction's uncommitted change; a non-repeatable read gets a different value when re-reading the same row; a phantom read sees new rows appear in a repeated query. Stronger isolation levels (up to
SERIALIZABLE) rule these out — at a cost in concurrency. - The default level differs per database. PostgreSQL defaults to
READ COMMITTED; don't assume you getSERIALIZABLEfor free — pick it explicitly when you need it. - Long transactions hold locks. An open transaction can block others and balloon storage; keep them short and commit (or roll back) promptly.
Go deeper
Eine Transaktion bündelt mehrere Schreibvorgänge zu einer Alles-oder-nichts-Einheit. Entweder landen alle Änderungen, oder keine — die Datenbank bleibt nie auf halbem Weg stehen.
Wo es vorkommt
- Überweisungen — ein Konto belasten, ein anderes gutschreiben, beides oder nichts.
- Bestellung aufgeben — Lager abbuchen und Bestellzeile anlegen, gemeinsam.
- Jedes Mehrfach-Update, das konsistent bleiben muss: doppelte Buchführung, Sitzplatzbuchung, Inventar.
Was es tut
Sie zieht eine Grenze um eine Gruppe von Statements, sodass das übrige System sie als einen einzigen Schritt sieht. Aus Sicht jeder anderen Transaktion ist sie entweder ganz passiert oder gar nicht — ein sichtbarer Zwischenzustand existiert nicht.
Atomicity gibt's gratis; Isolation ist der Teil, für den du zahlst — und deine Datenbank gibt dir standardmäßig ein schwächeres Level als SERIALIZABLE.
Wie es funktioniert
Du öffnest mit BEGIN, führst deine Statements aus und schließt mit COMMIT (dauerhaft machen) oder ROLLBACK (alles verwerfen). Die vier Garantien heißen ACID: Atomicity — alle Statements landen oder keines. Consistency — Regeln und Constraints bleiben wahr (die beiden Salden ergeben weiter dieselbe Summe). Isolation — parallele Transaktionen sehen die Halbarbeit der anderen nicht. Durability — einmal committed, übersteht die Änderung einen Crash.
Der Klassiker ist die Überweisung von 30 € von Ana zu Ben:
BEGIN;
UPDATE accounts SET balance = balance - 30 WHERE name = 'Ana';
UPDATE accounts SET balance = balance + 30 WHERE name = 'Ben';
COMMIT;
Scheitert die Gutschrift, nachdem die Belastung lief, macht ROLLBACK auch die Belastung rückgängig — die 30 € verschwinden nie unbemerkt.
Worauf achten
- Schwache Isolation lässt Anomalien durch. Ein Dirty Read sieht die uncommittete Änderung einer anderen Transaktion; ein Non-repeatable Read liest beim erneuten Lesen derselben Zeile einen anderen Wert; ein Phantom Read sieht in einer wiederholten Abfrage neue Zeilen auftauchen. Höhere Isolation Levels (bis
SERIALIZABLE) schließen das aus — auf Kosten der Nebenläufigkeit. - Das Default-Level ist je Datenbank verschieden. PostgreSQL nutzt standardmäßig
READ COMMITTED; verlass dich nicht darauf,SERIALIZABLEgratis zu bekommen — wähle es bewusst, wenn du es brauchst. - Lange Transaktionen halten Locks. Eine offene Transaktion kann andere blockieren und den Speicher aufblähen; halte sie kurz und committe (oder rolle zurück) zügig.