Kodokon kodokon.com

Transacciones: BEGIN, COMMIT, ROLLBACK y ACID

Haz atómicas tus escrituras con transacciones y comprende qué significan las garantías ACID en la práctica diaria.

8 min · 3 preguntas

Abrir esta lección en Kodokon

Una 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.

SQL
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);
La restricción CHECK prohíbe cualquier saldo negativo.

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).

SQL
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;
Transferencia atómica: 300 para alice, 320 para bruno.

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.

SQL
BEGIN;

UPDATE accounts
SET balance = balance - 400
WHERE owner = 'bruno';
-- Error: CHECK (balance >= 0) rejects the row.

ROLLBACK;

SELECT owner, balance FROM accounts;
Después de ROLLBACK, los saldos del último COMMIT quedan intactos.

Prueba de conocimientos

Comprueba que has retenido los puntos clave de esta lección.

  1. ¿Qué garantiza la atomicidad, la A de ACID?
    • Las consultas de la transacción se ejecutan más rápido
    • La transacción se aplica por completo o nada en absoluto
    • Dos transacciones nunca pueden leer la misma tabla
  2. Después de un ROLLBACK, ¿en qué estado queda la base de datos?
    • En el del último COMMIT, como si el BEGIN nunca hubiera ocurrido
    • Se conservan los UPDATE que tuvieron éxito antes del error
    • La base de datos permanece bloqueada hasta el siguiente BEGIN
  3. ¿Por qué 10 000 INSERT son mucho más rápidos en una sola transacción de SQLite?
    • SQLite comprime los datos insertados en bloque
    • Una sola sincronización a disco en el COMMIT en lugar de una por instrucción
    • Los índices se desactivan durante la transacción