Haz atómicas tus escrituras con transacciones y comprende qué significan las garantías ACID en la práctica diaria.
Abrir esta lección en KodokonUna transferencia bancaria son dos UPDATE: debitar una cuenta, acreditar la otra. Si la segunda falla, la base de datos miente. La transacción vuelve el bloque indivisible, con las garantías ACID: Atomicidad (todo o nada), Consistencia (las restricciones siguen siendo válidas), Isolation o aislamiento (las transacciones concurrentes nunca se ven a medio terminar), Durabilidad (un COMMIT sobrevive a un fallo). Para esta lección, prefiere el cliente real sqlite3: algunos entornos de pruebas web confirman automáticamente cada consulta.
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);El caso nominal: BEGIN abre la transacción, las escrituras se acumulan, COMMIT las hace definitivas todas a la vez. Entre medias, ninguna otra conexión ve el estado intermedio (alice debitada, bruno aún no acreditado).
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;Ahora el caso de fallo. Debitar 400 a bruno violaría CHECK (balance >= 0): la instrucción falla. Una sutileza de SQLite: por defecto, un error cancela la instrucción culpable pero deja la transacción abierta. Le corresponde a tu código de aplicación decidir: ROLLBACK para deshacer todo (el reflejo sensato), o continuar si el error es recuperable.
BEGIN;
UPDATE accounts
SET balance = balance - 400
WHERE owner = 'bruno';
-- Error: CHECK (balance >= 0) rejects the row.
ROLLBACK;
SELECT owner, balance FROM accounts;