BEGIN, COMMIT, ROLLBACK
Kurz gesagt: BEGIN beginnt eine Transaktion, COMMIT speichert ihre Änderungen, ROLLBACK macht sie rückgängig, und SAVEPOINT markiert einen Punkt, bis zu dem ROLLBACK TO zurückgehen kann.
Problem
Der Fehler, nach dem nichts fertig ist
Das Programm erhöht die Preise der Milchprodukte um 10 % und korrigiert in derselben Transaktion den Preis des Brotes. Die zweite Abfrage hat einen Fehler: Der Preis wird negativ. Führ sie aus:
Die zweite Abfrage ist abgebrochen. Und die erste? Wurde die Preiserhöhung bei den Milchprodukten zurückgenommen, oder ist sie durchgegangen?
Die Idee
Die Transaktion bleibt offen
Keins von beiden. SQLite macht nur die fehlgeschlagene Abfrage rückgängig. Die Transaktion bleibt offen, und die Preiserhöhung bei den Milchprodukten steckt darin, noch nicht bestätigt.
Probier es im selben Feld aus, ohne „Neue Datenbank“. Lösche den Text, schreib SELECT name, price FROM products WHERE category_id = 4; und führ es aus: Die Preise sind gestiegen. Dann schreib ROLLBACK; und führ die Preisabfrage noch einmal aus.
Deshalb hat ein Programm, das mit Transaktionen arbeitet, immer zwei Wege: Alles ist gut, also COMMIT; etwas ist fehlgeschlagen, also ROLLBACK. Sagt es nichts, hängt die Transaktion. Solange sie hängt, kann in SQLite niemand sonst in die Datenbank schreiben, und in PostgreSQL und MySQL wartet jeder, der dieselben Zeilen ändern will.
Genauer, für Neugierige
Wenn du in diesem Feld noch einmal BEGIN ausführst, ohne die alte Transaktion zu schließen, sagt SQLite „cannot start a transaction within a transaction“. PostgreSQL ist strenger: Nach einem Fehler ist die ganze Transaktion kaputt, und bis zum ROLLBACK weigert sich jede weitere Abfrage zu laufen.
Sieh es dir an
Was ich innen sehe
Innerhalb der Transaktion sind die Änderungen schon vor der Bestätigung sichtbar, aber nur für sie:
Eine andere Verbindung zur Datenbank (ein anderer Benutzer, ein anderes Programm) sieht noch die alten Preise. Die zwei Sitzungen nebeneinander sehen wir in der nächsten Lektion.
Die Idee
SAVEPOINT: zurück zu einem Punkt
Manchmal willst du nur einen Teil der Transaktion aufgeben. SAVEPOINT Name setzt einen Punkt, und ROLLBACK TO Name geht zu ihm zurück. Alles vor dem Punkt bleibt, und die Transaktion geht weiter.
Eine Lieferung: Das Brot ist angekommen (+10), die Getränke nicht. Sie werden aus Gewohnheit mit addiert und dann zurückgenommen:
Vom Brot sind es 10 mehr, bei den Getränken hat sich nichts geändert.
Übung
Nur das Brot wird teurer
Die Transaktion erhöht die Preise von Brot und Milchprodukten um 5 %. Die Shopleitung sagt: Die Milchprodukte behalten die alten Preise. Füge eine Zeile ein, sodass nur die Preiserhöhung bei den Milchprodukten zurückgenommen wird.
Lösung
BEGIN;
UPDATE products SET price = ROUND(price * 1.05, 2) WHERE category_id = 3;
SAVEPOINT dairy;
UPDATE products SET price = ROUND(price * 1.05, 2) WHERE category_id = 4;
ROLLBACK TO dairy;
COMMIT;
SELECT name, price FROM products WHERE category_id IN (3, 4);ROLLBACK TO dairy; anstelle des Kommentars. Das Brot ist teurer, die Milchprodukte haben die alten Preise, und die Transaktion endet mit COMMIT.
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Rechnen in einer Abfrage · UPDATE: Werte ändern · ACID: alles oder nichts
- Geht weiter in: Gleichzeitige Transaktionen · Schema-Migrationen · OLTP und OLAP · Wie du eine Datenbank wählst
- Aufgaben zum Thema: Transaktionen