Las transacciones ACID son un conjunto de cuatro propiedades (Atomicidad, Consistencia, Aislamiento y Durabilidad) que garantizan que las operaciones en una base de datos se procesen de manera confiable, segura y sin corromper los datos, incluso si ocurren fallos en el sistema.
Los 4 Pilares de ACID y Ejemplos
Atomicidad (Atomicity): Las transacciones son de "todo o nada". Si un paso de la transacción falla, la operación completa se cancela y el sistema vuelve a su estado original.
- Ejemplo: Al transferir de una cuenta a otra, se debe restar de la cuenta A y sumar a la cuenta B. Si el sistema falla justo después de restar el dinero (y antes de sumarlo), la atomicidad revierte el proceso para que el dinero no "desaparezca".
Consistencia (Consistency): La transacción debe cumplir con todas las reglas y restricciones definidas en la base de datos. Los datos siempre deben estar en un estado válido antes y después de la operación.
- Ejemplo: Si una regla establece que una cuenta bancaria no puede tener un saldo menor a , cualquier transacción que intente retirar dinero por encima del saldo disponible será rechazada por el sistema.
Aislamiento (Isolation): Si varias transacciones ocurren al mismo tiempo, el sistema las procesa como si estuvieran aisladas la una de la otra. Esto evita que los datos se mezclen o interfieran entre sí.
- Ejemplo: Si dos clientes intentan comprar la última entrada a un concierto al mismo tiempo, el aislamiento garantiza que un cliente complete la compra y reciba el boleto antes de que el segundo cliente pueda siquiera intentar la operación.
Durabilidad (Durability): Una vez que una transacción se confirma (guarda) con éxito, los cambios son permanentes en la base de datos. No se perderán ni siquiera si hay un corte de energía o un fallo total del servidor.
- Ejemplo: Recibes un correo de confirmación de compra en línea; aunque se apague el servidor del sistema de pagos un segundo después, tu compra seguirá registrada de forma permanente.
Demostración en PostgreSQL
Para demostrar cómo PostgreSQL maneja de forma nativa los 4 pilares de ACID, utilizaremos un caso clásico de transferencias bancarias.
1. Creación de la Tabla de Pruebas
Primero, ejecutamos este script para crear la tabla de cuentas con una restricción de saldo positivo (CHECK).
-- Crear tabla de cuentas bancarias
CREATE TABLE cuentas (
id SERIAL PRIMARY KEY,
cliente VARCHAR(50) NOT NULL,
saldo NUMERIC(10, 2) NOT NULL,
CONSTRAINT saldo_positivo CHECK (saldo >= 0)
);
-- Insertar datos iniciales para las pruebas
INSERT INTO cuentas (cliente, saldo) VALUES
('Alicia', 500.00),
('Bruno', 100.00);
2. Ejemplos de los 4 Pilares en SQL
Atomicidad (Todo o nada)
Si una de las operaciones dentro del bloque BEGIN y COMMIT falla, todo el bloque se cancela (ROLLBACK).
BEGIN;
-- Paso 1: Descontar de la cuenta de Alicia
UPDATE cuentas SET saldo = saldo - 100 WHERE cliente = 'Alicia';
-- Paso 2: Ocurre un error simulado (la columna 'cuenta_destino' no existe)
UPDATE cuentas SET saldo_incorrecto = saldo + 100 WHERE cliente = 'Bruno';
-- Al fallar el Paso 2, PostgreSQL cancela automáticamente todo.
-- El saldo de Alicia regresa a 500.00 de forma automática.
COMMIT;
Consistencia (Reglas de integridad)
PostgreSQL garantiza que ninguna transacción viole las restricciones establecidas (como el CHECK de saldo mayor a cero).
BEGIN;
-- Intentar retirar más dinero del que Bruno tiene disponible ($100)
UPDATE cuentas SET saldo = saldo - 150 WHERE cliente = 'Bruno';
-- RESULTADO: PostgreSQL arrojará un error de violación de restricción:
-- "ERROR: el nuevo registro para la relación «cuentas» viola la restricción check «saldo_positivo»"
-- La base de datos aborta la transacción y mantiene los datos válidos.
COMMIT;
Aislamiento (Control de concurrencia)
PostgreSQL utiliza niveles de aislamiento (por defecto READ COMMITTED) y bloqueos para que dos transacciones simultáneas no interfieran entre sí. [2]
- Sesión 1 (Usuario A - Ejecuta primero):
BEGIN;
-- Bloquea la fila de Alicia para actualizarla
UPDATE cuentas SET saldo = saldo - 50 WHERE cliente = 'Alicia';
-- (Aún no hace COMMIT, mantiene el bloqueo)
- Sesión 2 (Usuario B - Ejecuta al mismo tiempo):
BEGIN;
-- Intenta modificar la misma fila de Alicia
UPDATE cuentas SET saldo = saldo - 20 WHERE cliente = 'Alicia';
-- NOTA: PostgreSQL pondrá esta Sesión 2 en espera ("en cola")
-- hasta que la Sesión 1 ejecute COMMIT o ROLLBACK.
Durabilidad (Persistencia garantizada)
Una vez que ejecutas COMMIT, PostgreSQL escribe la operación en el WAL (Write-Ahead Logging) en el disco duro antes de responder exitosamente.
BEGIN;
UPDATE cuentas SET saldo = saldo + 200 WHERE cliente = 'Alicia';
COMMIT;
-- En este punto exacto, el cambio es permanente.
-- Si el servidor sufre un apagón repentino un milisegundo después,
-- al reiniciar, PostgreSQL recuperará el estado usando los registros WAL.
Se recomienda crear procedimientos almacenada (Stored Procedure) en PL/pgSQL para automatizar estas transferencias de forma segura.
Recomendación:
Puedes revisar detalles técnicos adicionales y casos de uso en la guía de Databricks sobre Transacciones ACID.
0 Comentarios