In SQL ermöglichen Transaktionen, mehrere Operationen (insert/update/delete) in einer atomaren Einheit zusammenzufassen, die entweder vollständig angewendet oder zurückgerollt werden kann. Der Lebenszyklus einer Transaktion basiert auf den Befehlen:
BEGIN oder START TRANSACTION — Beginn der Transaktion;COMMIT — Bestätigung der Änderungen;ROLLBACK — Rückgängigmachen aller Änderungen innerhalb der Transaktion.SQL unterstützt Isolationsstufen von Transaktionen (Read Uncommitted, Read Committed, Repeatable Read, Serializable), die die Sichtbarkeit der Daten zwischen parallelen Transaktionen definieren und vor Problemen wie "Dirty Reads" oder "Phantomzeilen" schützen.
Zur Kontrolle der Datenintegrität sind folgende Maßnahmen erforderlich:
SELECT ... FOR UPDATE).Beispiel in PostgreSQL:
BEGIN; -- Abrufen und Blockieren der Produktzeile SELECT * FROM inventory WHERE id = 1 FOR UPDATE; UPDATE inventory SET quantity = quantity - 1 WHERE id = 1; COMMIT;
Welcher Wert ist standardmäßig in beliebten DBMS (PostgreSQL, MySQL) für die Isolationsstufe gesetzt und wie unterscheidet er sich von SERIALIZABLE?
Antwort:
In PostgreSQL wird standardmäßig die Isolationsstufe Read Committed verwendet — in dieser sieht die Transaktion nur die zum Zeitpunkt der Anfrage bestätigten Daten, aber es können "nicht wiederholbare Lesevorgänge" (non-repeatable reads) auftreten.
In MySQL (InnoDB) — Repeatable Read. Der Unterschied zu Serializable besteht darin, dass nur Letzteres alle phantom oder parallelen Änderungen vollständig verhindert, aber deutlich langsamer zu arbeiten ist aufgrund globaler Sperren.
Beispiel:
-- In Repeatable Read kann SELECT die gleichen Zeilen zurückgeben, während in Read Committed neue zwischen zwei SELECT innerhalb der Transaktion erscheinen können.
Geschichte
In einem großen Finanzsystem kam es während massenhaftem Geldtransfer bei niedriger Isolationsstufe (Read Committed) gelegentlich zu Situationen, in denen der gleiche Saldo gleichzeitig von mehreren Transaktionen verwendet wurde. Dies führte zu doppelten Ausgaben (race condition). Nach dem Wechsel zu
Serializableund einem kompetenten Management von Sperren verschwand das Problem.
Geschichte
Im E-Commerce führte eine Transaktion mit
UPDATE product SET stock = stock - 1ohne Umhüllung in einer Transaktion dazu, dass mehr Produkte verkauft wurden, als auf Lager waren. Das Problem trat erst bei einer großen Anzahl konkurrierender Bestellungen auf. Lösung — Nutzung von Transaktionen und Zeilensperren überSELECT ... FOR UPDATE.
Geschichte
In einem Logistiksystem wurde in einer der Tabellen bei häufigen Updates das explizite Committen vergessen. Bei Störungen gingen Teile der Daten aufgrund von Auto-Commit oder fehlerhaftem Rollback verloren. Ergebnis — Verlust von Datensätzen und kostspielige Audits.