Fundamentos
8 min de lectura·

Qué es ACID: atomicidad, consistencia, aislamiento y durabilidad

ACID son las cuatro propiedades que un SGBD garantiza al ejecutar transacciones: Atomicity (atomicidad), Consistency (consistencia), Isolation (aislamiento) y Durability (durabilidad). Juntas significan una sola cosa: puedes fiarte de los datos aunque el servidor se caiga a mitad de una operación y miles de clientes accedan a la base de datos a la vez.

Una transacción es un grupo de operaciones SQL que se ejecuta como un todo: o todas las operaciones terminan con éxito, o no se ejecuta ninguna. El ejemplo clásico es una transferencia de dinero:

MySQL 8.4
START TRANSACTION;

UPDATE accounts SET balance = balance - 1000 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE account_id = 2;

COMMIT;

Entre los dos UPDATE puede pasar cualquier cosa: un corte de luz, una caída de la red, que se cuelgue el proceso del SGBD. Si la primera orden se ejecuta y la segunda no, mil euros desaparecen sin más. Las propiedades ACID existen precisamente para que historias así sean imposibles. Veámoslas una a una.

Las cuatro propiedades ACID

A: Atomicity, atomicidad

Una transacción es indivisible: o se ejecutan todas sus operaciones, o ninguna.

En el ejemplo de la transferencia, la atomicidad garantiza que no existe ningún estado de la base de datos en el que el dinero se haya cargado en una cuenta sin abonarse en la otra. Si algo sale mal en cualquier paso, el SGBD hace un rollback (deshace la transacción): devuelve los datos al estado que tenían al empezarla, como si nunca hubiera existido.

El rollback también se puede lanzar a mano con la orden ROLLBACK:

MySQL 8.4
START TRANSACTION;

UPDATE accounts SET balance = balance - 1000 WHERE account_id = 1;
-- cambio de planes: deshacemos todos los cambios de esta transacción
ROLLBACK;

Por dentro, el SGBD lleva un registro de cambios: antes de modificar los datos, anota qué va a hacer y cómo deshacerlo. Tras un fallo, la base de datos se recupera a partir de ese registro: las transacciones confirmadas se completan y las que quedaron a medias se deshacen.

C: Consistency, consistencia

Una transacción lleva la base de datos de un estado correcto a otro estado correcto.

Qué es «correcto» lo definen las reglas descritas en el esquema: las restricciones NOT NULL, UNIQUE y CHECK, las claves foráneas y los triggers. Si dentro de una transacción se incumple alguna regla (por ejemplo, el saldo queda negativo con la restricción CHECK (balance >= 0)), la transacción se deshace entera.

Un matiz importante: el SGBD solo comprueba las reglas que le has descrito. Si la regla «la suma de los cargos es igual a la suma de los abonos» solo existe en la cabeza del desarrollador, la base de datos no la protegerá. La consistencia es un trabajo conjunto del SGBD y de quien diseña el esquema.

I: Isolation, aislamiento

Las transacciones en paralelo no ven los estados intermedios de las demás.

Mientras un cliente hace una transferencia, otro está sumando en ese mismo instante los saldos de todas las cuentas. Sin aislamiento, el segundo cliente podría ver la base de datos «a medio camino»: el dinero ya cargado, pero todavía sin abonar. El total le saldría con un error de mil euros.

Lo ideal sería que las transacciones se comportaran como si se ejecutaran estrictamente una detrás de otra. Pero el aislamiento total sale caro: las transacciones tienen que esperarse unas a otras. Por eso los SGBD ofrecen soluciones de compromiso, los niveles de aislamiento. Cuanto más bajo es el nivel, más rápido funciona la base de datos y más rarezas pueden observar las transacciones en paralelo. A esas rarezas se les llama anomalías de lectura:

  • Lectura sucia (dirty read). Una transacción ve cambios que otra transacción todavía no ha confirmado. Si esa otra se deshace, los datos leídos nunca existieron «oficialmente».
  • Lectura no repetible (non-repeatable read). Una transacción lee la misma fila dos veces y obtiene valores distintos, porque, entre las dos lecturas, otra transacción ha modificado la fila y la ha confirmado.
  • Lectura fantasma (phantom read). Una transacción ejecuta dos veces la misma consulta con una condición y la segunda vez ve filas nuevas que otra transacción ha insertado entretanto.

La forma más sencilla de ver una anomalía en directo es una línea de tiempo con dos sesiones en paralelo. Esta es una lectura no repetible en el nivel READ COMMITTED:

PasoSesión ASesión B
1BEGIN;
2SELECT balance ... → 100
3UPDATE ... SET balance = 50; COMMIT;
4SELECT balance ... → 50
5Una misma consulta, dos respuestas diferentes

La sesión A no ha hecho nada entre los pasos 2 y 4, pero el mundo ha cambiado bajo sus pies. En el nivel REPEATABLE READ, el paso 4 devolvería los mismos 100: la transacción trabaja con una instantánea de los datos tomada en el momento en que empezó.

El estándar SQL describe cuatro niveles de aislamiento, y cada uno impide más anomalías que el anterior:

Nivel de aislamientoLectura suciaLectura no repetibleLectura fantasma
READ UNCOMMITTEDposibleposibleposible
READ COMMITTEDnoposibleposible
REPEATABLE READnonoposible
SERIALIZABLEnonono

Por defecto, PostgreSQL trabaja en el nivel READ COMMITTED y MySQL (InnoDB) en REPEATABLE READ. En la práctica casi siempre es suficiente, pero conviene saber qué anomalías son posibles en tu nivel: los bugs «intermitentes» en informes y contadores suelen venir justo de aquí.

El nivel se puede cambiar para una transacción concreta:

MySQL 8.4
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
-- lógica en la que la exactitud es crítica
COMMIT;

Una transacción ha ejecutado dos veces la consulta SELECT COUNT(*) FROM orders WHERE status = 'new' y ha obtenido números distintos: entre las dos consultas, otra transacción ha añadido pedidos. ¿Cómo se llama esta anomalía?

D: Durability, durabilidad

Si una transacción se ha confirmado, su resultado no se perderá.

En cuanto el SGBD responde «COMMIT ejecutado», los cambios sobreviven a lo que sea: un apagado de emergencia del servidor, la caída del proceso, un reinicio. Se consigue porque, antes de confirmar, se fuerza la escritura en disco de una entrada sobre la transacción en el registro (en PostgreSQL se llama WAL, write-ahead log, y en MySQL InnoDB, redo log). Aunque los datos de las tablas no hayan llegado a actualizarse, después del reinicio la base de datos los llevará al estado correcto a partir del registro.

El servidor de base de datos se ha reiniciado por un fallo justo cuando una transacción había ejecutado el primero de sus dos UPDATE. ¿Qué pasará con ese cambio después del reinicio?

ACID vs BASE: ¿y qué pasa con NoSQL?

En el mundo de los almacenes NoSQL distribuidos se suele usar otro conjunto de compromisos, BASE: Basically Available, Soft state, Eventually consistent. La idea es que el sistema siempre responde, pero los datos de distintos nodos pueden diferir durante un tiempo y acabar coincidiendo «con el tiempo».

No es «peor» ni «mejor» que ACID: es otra elección. Un sistema de pagos necesita el rigor de ACID, porque una transferencia perdida es inadmisible. A un contador de «me gusta» le basta con BASE: no pasa nada si el número va un segundo por detrás. Muchos sistemas modernos combinan ambos enfoques para distintas partes de los datos.

Qué preguntan en las entrevistas

ACID es uno de los temas más frecuentes en las entrevistas de SQL y bases de datos. Preguntas típicas:

  • Explica qué significan las siglas ACID y cada una de las propiedades. Basta con el ejemplo de la transferencia: cubre las cuatro letras.
  • ¿En qué se diferencia la atomicidad de la consistencia? La atomicidad va de «todo o nada»; la consistencia, de que el estado final cumpla las reglas del esquema.
  • ¿Qué niveles de aislamiento conoces y cuál se usa por defecto? Aquí esperan la tabla de arriba más los valores por defecto de tu SGBD.
  • ¿Qué es una lectura sucia y en qué nivel es posible? Solo en READ UNCOMMITTED.
  • ¿Cómo garantiza la base de datos la durabilidad si los datos se guardan en caché en memoria? La palabra clave es el registro de escritura anticipada (WAL/redo log): antes de confirmar, lo que llega al disco es la entrada del registro, no las propias páginas de datos.

Siguientes pasos

ACID es teoría que conviene afianzar enseguida con práctica:

Artículos relacionados