#datenbank Kontext: Datenbanken --- ACID-Transaktionen sind ein zentrales Konzept in der Datenbankwelt – vor allem dort, wo Daten „kritisch“ sind (z.B. Banking, Buchhaltung, Bestellungen). Ich führe dich Schritt für Schritt ein, ohne Vorwissen vorauszusetzen. --- ## 1. Grundidee: Was ist eine Transaktion? Stell dir eine Transaktion als **logische Einheit von mehreren Datenbankoperationen** vor, die entweder **komplett** oder **gar nicht** ausgeführt werden soll. Beispiel (Banküberweisung): - Konto A: 100 € → 80 € (10 € werden abgebucht) - Konto B: 50 € → 70 € (10 € werden gutgeschrieben) Diese beiden Schritte gehören zusammen: - Es darf nicht passieren, dass bei A 10 € abgebucht werden, ohne dass sie bei B ankommen. - Oder dass B 10 € bekommt, ohne dass sie bei A abgezogen werden. Beide Aktionen zusammen bilden eine **Transaktion**. --- ## 2. Was bedeutet ACID? **ACID** steht für vier Eigenschaften, die Transaktionen in klassischen relationalen Datenbanken gewährleisten sollen: 1. **A – Atomicity (Atomarität)** 2. **C – Consistency (Konsistenz)** 3. **I – Isolation** 4. **D – Durability (Dauerhaftigkeit)** Ich erkläre jede mit einfachen Beispielen. --- ### 2.1 Atomicity (Atomarität) **Definition:** Eine Transaktion wird **entweder vollständig oder gar nicht** ausgeführt. Es gibt keinen „halben“ Zustand. Beispiel: Wieder unsere Banküberweisung: 1. 10 € von Konto A abbuchen 2. 10 € Konto B gutschreiben Passiert in der Mitte ein Fehler (z.B. Stromausfall nach Schritt 1), sorgt Atomicity dafür: - Entweder werden **beide** Schritte ausgeführt - oder **beide rückgängig gemacht** (Rollback) Es darf nicht der Zustand entstehen: - Konto A: -10 € - Konto B: unverändert Das wäre ein inkonsistenter Zustand – Atomicity verhindert das. --- ### 2.2 Consistency (Konsistenz) **Definition (aus Sicht der Datenbankregeln):** Eine Transaktion bringt die Datenbank von einem **gültigen Zustand** in einen **anderen gültigen Zustand**, gemäß den definierten Regeln (Constraints, Geschäftsregeln). Wichtig: Konsistenz bezieht sich nicht nur auf „richtige Daten“, sondern auf die **Einhaltung von Regeln**, z.B.: - Fremdschlüssel-Beziehungen (z.B. jede Bestellung gehört zu einem existierenden Kunden) - Eindeutigkeit (z.B. E-Mail-Adressen sind eindeutig) - Wertebereiche (z.B. Kontostand darf nicht negativ sein, wenn das System das verbietet) Beispiel: - Regel: Kontostand darf nicht unter 0 fallen. - Transaktion: Konto mit 5 € soll 10 € abbuchen. - Datenbank oder Geschäftslogik verhindern, dass diese Transaktion „erfolgreich bestätigt“ wird. - Nach der Transaktion ist die Datenbank immer noch in einem Zustand, in dem alle Regeln gelten. Konsistenz sagt also: „Wenn du eine Transaktion beginnst, die gültige Daten voraussetzt, dann endet sie (falls sie commitet wird) wieder mit gültigen Daten.“ --- ### 2.3 Isolation **Definition:** Parallele Transaktionen **beeinflussen sich nicht gegenseitig** in einer Art und Weise, die zu inkonsistenten Ergebnissen führt. Jede Transaktion „fühlt sich so an“, als wäre sie die einzige, die gerade läuft. Isolation wird in der Praxis über **Isolation Levels** gesteuert (z.B. READ COMMITTED, REPEATABLE READ, SERIALIZABLE), aber fürs Grundverständnis reicht: Beispiel (gleichzeitige Transaktionen): - T1: Bucht 10 € von Konto A zu Konto B um. - T2: Prüft den Kontostand von Konto A für eine Kreditprüfung. Ohne Isolation könnte T2 gerade dann den Kontostand lesen, wenn T1 mitten in der Überweisung ist (z.B. A: 90 €, B: noch nicht aktualisiert). Je nach Isolationsebene verhindert das System: - „schmutzige“ Reads (lesen von unbestätigten Zwischenständen), - instabile Wiederholungen (derselbe SELECT liefert in einer Transaktion plötzlich andere Ergebnisse), - Phantom Reads (neue Datensätze tauchen „plötzlich“ in einer laufenden Transaktion auf). Einfach gesagt: Isolation schützt davor, dass sich parallele Transaktionen gegenseitig „in die Quere kommen“. --- ### 2.4 Durability (Dauerhaftigkeit) **Definition:** Wenn eine Transaktion **erfolgreich abgeschlossen** (committed) ist, bleiben die Änderungen **dauerhaft** gespeichert – auch bei: - Stromausfall - Absturz des Servers - Neustart der Datenbank Technisch wird das oft über: - Write-Ahead-Log (Transaktionslog), - Journaling, - redundante Speicherung umgesetzt. Beispiel: - Überweisung wurde committed. - Direkt danach fällt der Strom aus. - Nach Neustart der Datenbank sind die Kontostände **so**, wie sie nach der Überweisung sein sollen. Keine „zufällige Rücksetzung“ auf den Stand davor. --- ## 3. Abgrenzung zu verwandten Begriffen ### 3.1 Transaktion vs. einzelne SQL-Operation - Eine **Transaktion** kann aus einer oder mehreren SQL-Anweisungen (z.B. mehreren INSERT, UPDATE, DELETE) bestehen. - Ohne explizite Transaktion wird oft jede Anweisung automatisch als eigene, kleine Transaktion behandelt (Auto-Commit-Modus). Beispiel: - Zwei separate UPDATE-Befehle ohne Transaktion: - Es kann passieren, dass nur der erste erfolgreich ist und der zweite fehlschlägt – dann hast du einen halben Zustand. - In einer Transaktion: - Beides wird zusammen behandelt – im Fehlerfall wird alles zurückgerollt. --- ### 3.2 ACID vs. BASE (in verteilten / NoSQL-Systemen) In vielen verteilten Systemen (z.B. große NoSQL-Datenbanken) wird statt ACID eher das Prinzip **BASE** verfolgt: - **B**asically **A**vailable – Das System ist grundsätzlich verfügbar. - **S**oft-state – Der Zustand kann sich ändern, auch ohne explizite Transaktion. - **E**ventual consistency – Daten werden **irgendwann konsistent**, nicht unbedingt sofort. Vergleich: - ACID: Strenge Garantien, dafür manchmal langsamer oder schwerer skalierbar. - BASE: Weniger strenge Garantien, dafür oft leicht horizontal skalierbar (über viele Server verteilt). Beispiel: - Social-Media-Likes: - Es ist ok, wenn du für ein paar Sekunden oder Minuten leicht unterschiedliche Like-Zahlen auf verschiedenen Geräten siehst. - Bankkonto: - Es ist **nicht** ok, wenn der Kontostand „irgendwann mal“ stimmt. Hier will man ACID. --- ### 3.3 Konsistenz (ACID) vs. Konsistenz (CAP-Theorem) Der Begriff „Konsistenz“ wird auch im **CAP-Theorem** verwendet (bei verteilten Systemen). Dort bedeutet er etwas anderes: - ACID-Konsistenz: Einhaltung von Datenbankregeln (Constraints, Geschäftslogik). - CAP-Konsistenz: Alle Knoten eines verteilten Systems sehen dieselben Daten zur selben Zeit. Es ist wichtig, diese beiden Bedeutungen nicht zu verwechseln. --- ## 4. Welche Probleme lösen ACID-Transaktionen? ### 4.1 Vermeidung halbfertiger Zustände Ohne Atomicity: - Stromausfall mitten in einer Update-Sequenz → Daten inkonsistent. Mit ACID: - Entweder alles oder nichts → Daten bleiben konsistent. --- ### 4.2 Schutz vor parallelen Zugriffskonflikten Typische Probleme ohne Isolation: 1. **Lost Update (verlorenes Update)** - Zwei Benutzer lesen denselben Datenstand, ändern ihn unabhängig und speichern beide. - Die zweite Speicherung überschreibt die erste, ohne es zu merken. Beispiel: - Lagerbestand: 10 Stück - Benutzer A: Reserviert 3 (denkt: 10 → 7) - Benutzer B: Reserviert 4 (denkt: 10 → 6) - Ohne Schutz: Endergebnis könnte 6 sein (Reservierung von A geht „verloren“). - Mit Isolation/Locks: Das System stellt sicher, dass die Updates korrekt nacheinander verarbeitet werden. 2. **Dirty Read (schmutziges Lesen)** - Eine Transaktion liest Änderungen, die eine andere Transaktion noch gar nicht committed hat. - Wenn die zweite Transaktion zurückgerollt wird, hat man auf falschen Daten gearbeitet. 3. **Non-repeatable Read & Phantom Read** - Eine Transaktion liest dieselben Daten mehrmals, aber bekommt unterschiedliche Ergebnisse, weil andere Transaktionen dazwischen geschrieben haben. - Oder es tauchen plötzlich zusätzliche/fehlende Zeilen auf. ACID + passende Isolationsebene reduziert oder verhindert solche Probleme. --- ### 4.3 Sicherung kritischer Geschäftsprozesse Wo ACID typisch ist: - Bank- und Finanzsysteme - Flugsitz-Reservierungssysteme - Warenwirtschaft / Bestellabwicklung - Ticketverkauf (Konzert, Bahn, Flug) Beispiel Tickets: - Nur 1 Ticket übrig. - 2 Leute versuchen gleichzeitig, es zu kaufen. - ACID-Transaktionen sorgen dafür, dass am Ende nur eine Person das Ticket bekommt, nicht beide. --- ## 5. Welche Herausforderungen bringen ACID-Transaktionen mit sich? ACID klingt perfekt, hat aber trade-offs. ### 5.1 Performance und Skalierbarkeit - Starke Isolation und Konsistenz können **langsamer** sein, weil: - Locks (Sperren) auf Zeilen/Tabellen gesetzt werden, - viele Logs geschrieben werden müssen, - parallele Zugriffe begrenzt werden. Beispiel: - In einem stark frequentierten Online-Shop könnten lange laufende Transaktionen zu Warteschlangen führen: - Kunden müssen warten, bevor ihre Updates durchgeführt werden können. --- ### 5.2 Deadlocks (Verklemmungen) Wenn mehrere Transaktionen sich gegenseitig sperren, kann es zu einem **Deadlock** kommen: Beispiel: - T1: - Sperrt Zeile X - Will dann Zeile Y sperren (die aber schon von T2 gesperrt ist) - T2: - Sperrt Zeile Y - Will dann Zeile X sperren (die aber schon von T1 gesperrt ist) Beide warten aufeinander → Niemand kommt weiter. Die Datenbank muss Deadlocks erkennen und eine Transaktion abbrechen (Rollback), damit sich das System wieder erholen kann. --- ### 5.3 Lange laufende Transaktionen - Je länger eine Transaktion läuft, desto länger hält sie Sperren. - Das kann viele andere Benutzer blockieren. Beispiel: - Ein Report, der mehrere Minuten läuft, wird innerhalb einer Transaktion ausgeführt. - In dieser Zeit können andere nicht ordentlich auf dieselben Daten zugreifen (je nach Isolationsebene). Deshalb: In der Praxis versucht man, Transaktionen so **kurz wie möglich** zu halten. --- ### 5.4 Verteilte Transaktionen (über mehrere Systeme) Wenn eine Transaktion **über mehrere Datenbanken oder Services** geht, wird es komplex: Beispiel: - Bestellsystem: - Reserviert Ware in Lager-Datenbank A - Erstellt Rechnung in Finanz-Datenbank B Um ACID über beide Systeme zu garantieren, braucht man z.B.: - 2-Phase-Commit (2PC), - spezielle Transaktionskoordinatoren. Probleme: - Komplex, fehleranfällig, - schlechte Performance, - schlechte Skalierbarkeit in großen, verteilten Systemen. Darum verzichten moderne Microservice-Architekturen oft auf verteilte ACID-Transaktionen und nutzen stattdessen: - Eventual Consistency, - Sagas (geschäftliche, verteilte Abläufe mit Kompensationsaktionen). --- ### 5.5 Komplexität in der Anwendungslogik - Wenn Entwickler die Eigenschaften von Isolation, Locks, Deadlocks etc. nicht verstehen, können: - unerwartete Blockaden, - merkwürdige Nebenwirkungen, - Performanceprobleme auftreten. Deshalb ist ein grundlegendes Verständnis von ACID und Transaktionen auch für Anwendungsentwickler wichtig, nicht nur für Datenbankadministratoren. --- ## 6. Praxisnahe Beispiele im Überblick ### Beispiel 1: Bestellprozess im Online-Shop Schritte, die typischerweise in einer Transaktion laufen können: 1. Kundenbestellung speichern. 2. Lagerbestand reduzieren. 3. Reservierte Waren markieren. 4. Zahlstatus erfassen (z.B. „Bezahlung ausstehend“). Mit ACID: - Wenn in Schritt 2 der Lagerbestand negativ würde → Transaktion fehlschlägt → nichts wird dauerhaft gespeichert. - Kein Zustand „Bestellung existiert, aber Lagerbestand stimmt nicht“. --- ### Beispiel 2: Benutzerregistrierung Schritte: 1. Benutzerkonto anlegen (INSERT in `users`). 2. Authentifizierungsdaten anlegen (INSERT in `credentials`). 3. Willkommensguthaben in ein Bonuskonto einzahlen (INSERT in `bonus_accounts`). Mit ACID: - Entweder alle drei Inserts werden erfolgreich committed - oder keiner. - Kein Benutzer ohne Credentials, kein Bonuskonto ohne Benutzer. --- ### Beispiel 3: Rechnungsstellung Schritte: 1. Rechnung anlegen. 2. Rechnungsposten anlegen. 3. Offenen Posten im Finanzsystem erzeugen. Mit ACID: - Wenn das Anlegen der Rechnungsposten fehlschlägt, wird auch die Rechnung selbst zurückgerollt. - Es gibt keine „leere Rechnung“. --- ## 7. Zusammenfassung - **Transaktionen** fassen mehrere Operationen zu einer Einheit zusammen. - **ACID**-Eigenschaften sorgen dafür, dass diese Einheiten: - **A**tomar sind (alles oder nichts), - **C**onsistent bleiben (Regeln bleiben gültig), - **I**soliert laufen (parallele Transaktionen stören sich nicht „unsichtbar“), - **D**auerhaft gespeichert werden (Commit ist endgültig, auch bei Abstürzen). **Sie lösen vor allem:** - Teilweise Updates, - Inkonsistenzen durch Fehler, - Probleme durch parallele Zugriffe. **Herausforderungen sind:** - Performance, - Skalierung, - Deadlocks, - Komplexität (vor allem in verteilten Systemen). Wenn du möchtest, können wir als nächsten Schritt: - konkrete SQL-Beispiele (z.B. in PostgreSQL oder MySQL) durchgehen, oder - tiefer in Isolation Levels (READ COMMITTED, REPEATABLE READ, SERIALIZABLE) einsteigen.