Mache deine Schreibvorgänge mit Transaktionen atomar und verstehe, was die ACID-Garantien im Alltag bedeuten.
Diese Lektion in Kodokon öffnenEine Banküberweisung besteht aus zwei UPDATEs: ein Konto belasten, das andere gutschreiben. Schlägt das zweite fehl, lügt die Datenbank. Die Transaktion macht den Block unteilbar, mit den ACID-Garantien: Atomicity (alles oder nichts), Consistency (die Constraints bleiben gültig), Isolation (gleichzeitige Transaktionen sehen sich nie halbfertig), Durability (ein COMMIT überlebt einen Absturz). Bevorzuge für diese Lektion den echten sqlite3-Client: Manche Web-Sandboxes committen jede Abfrage automatisch.
CREATE TABLE accounts (
id INTEGER PRIMARY KEY,
owner TEXT NOT NULL,
balance REAL NOT NULL CHECK (balance >= 0)
);
INSERT INTO accounts (owner, balance)
VALUES
('alice', 500.0),
('bruno', 120.0);Der Normalfall: BEGIN öffnet die Transaktion, die Schreibvorgänge sammeln sich an, COMMIT macht sie alle auf einmal endgültig. Dazwischen sieht keine andere Verbindung den Zwischenzustand (alice belastet, bruno noch nicht gutgeschrieben).
BEGIN;
UPDATE accounts
SET balance = balance - 200
WHERE owner = 'alice';
UPDATE accounts
SET balance = balance + 200
WHERE owner = 'bruno';
COMMIT;
SELECT owner, balance FROM accounts;Jetzt der Fehlerfall. bruno um 400 zu belasten würde CHECK (balance >= 0) verletzen: Die Anweisung schlägt fehl. Eine SQLite-Feinheit: Standardmäßig bricht ein Fehler die fehlerhafte Anweisung ab, lässt die Transaktion aber offen. Es liegt an deinem Anwendungscode zu entscheiden: ROLLBACK, um alles rückgängig zu machen (der vernünftige Reflex), oder weitermachen, wenn der Fehler behebbar ist.
BEGIN;
UPDATE accounts
SET balance = balance - 400
WHERE owner = 'bruno';
-- Error: CHECK (balance >= 0) rejects the row.
ROLLBACK;
SELECT owner, balance FROM accounts;