Transacciones ACID
Cómo las bases de datos garantizan la integridad absoluta de las operaciones de lectura y escritura en entornos concurrentes.
¿Qué es una transacción?
Un conjunto de operaciones ejecutadas sobre una base de datos que se tratan como una única unidad atómica e indivisible de trabajo. O se completan todas las operaciones exitosamente, o el sistema vuelve al estado previo exacto.
Descontar $10.000 de tu cuenta
UPDATE cuentas SET saldo = saldo - 10000
Entregar los billetes en el cajero
HARDWARE_DISPENSE_CASH()
Las 4 Propiedades ACID
El motor de base de datos aplica estrictamente estas cuatro reglas para garantizar que los datos nunca se corrompan.
Atomicidad
UNIDAD DE TODO O NADATodas las operaciones de la transacción se aplican de forma completa, o no se aplica ninguna. Si ocurre un fallo, todo cambio en memoria se deshace (Rollback).
Consistencia
REGLAS E INTEGRIDADLa base de datos pasa de un estado válido a otro estado válido, respetando todas las restricciones (claves foráneas, triggers, reglas de negocio y chequéos).
Aislamiento
CONCURRENCIA INDEPENDIENTECada transacción se ejecuta como si fuera la única en el sistema. Las transacciones concurrentes no ven cambios intermedios sin confirmar de otras.
Durabilidad
PERSISTENCIA PERMANENTEUna vez confirmada la transacción (Commit), los cambios quedan grabados de forma permanente en el almacenamiento no volátil, resistiendo cortes de energía.
Ciclo de vida de una transacción
Etapas por las que transita una transacción desde su apertura hasta su cierre final.
Ejemplo: Transferencia Bancaria
Observá cómo actúan la Atomicidad y Consistencia al transferir $10.000 entre la Cuenta A y la Cuenta B.
UPDATE cuentas SET saldo = saldo - 10000 WHERE id = 'A';
UPDATE cuentas SET saldo = saldo + 10000 WHERE id = 'B';
COMMIT;
Anomalías por falta de Aislamiento
Cuando múltiples transacciones acceden a las mismas filas de la base de datos simultáneamente sin control adecuado.
SELECT stock FROM productos WHERE id = 482 FOR UPDATE;
T2 lee un valor modificado por T1 que aún no ha sido confirmado (uncommitted). Si T1 aborta, T2 habrá operado con datos ficticios.
T1 realiza lecturas repetidas de un conjunto de datos mientras T2 altera dichos datos a mitad del proceso, generando reportes inconsistentes.
Técnicas de Control de Concurrencia
Mecanismos utilizados por el DBMS para prevenir anomalías manteniendo el rendimiento óptimo.
🔒 Bloqueos (Locking)
Marcadores sobre filas o tablas. Compartido (Shared) permite lecturas simultáneas. Exclusivo (Exclusive) bloquea tanto lecturas como escrituras a otras transacciones.
🚫 Interbloqueo (Deadlock)
Dos o más transacciones quedan bloqueadas mutuamente en un ciclo infinito de espera por recursos retenidos por la otra.
⛺ Protocolo de Bloqueo en 2 Fases (2PL)
Garantiza la seriahilidad. Fase de Crecimiento (solo adquiere bloqueos) seguida de la Fase de Contracción (solo libera bloqueos).
🎫 Marcas Temporales (Timestamps & MVCC)
Cada transacción recibe un identificador secuencial. MVCC (Multi-Version Concurrency Control) mantiene versiones de filas para leer sin bloquear.
Recuperación ante fallos: WAL Log
Para cumplir con la Durabilidad (D), las bases de datos utilizan el patrón Write-Ahead Logging (WAL). Todo cambio se escribe primero en el archivo de log secuencial en disco antes de modificarse en las páginas de datos en RAM.
Buffer Pool
Modificaciones rápidas en caliente (Páginas sucias).
WAL Disk Log
Registro inmutable previo de cada operación (UNDO/REDO).
Data Files
Persistencia final en las tablas físicas.
Niveles de Aislamiento en SQL
Seleccioná cada nivel de aislamiento estándar ANSI/ISO SQL para ver dinámicamente qué anomalías están permitidas y cuáles son bloqueadas por el motor.
READ COMMITTED
Evita lecturas sucias asegurando que solo se lean datos confirmados con Commit. Es el nivel predeterminado en la mayoría de DBMS (PostgreSQL, SQL Server, Oracle).
Savepoints: Rollback Parcial
Los Savepoints permiten definir puntos de restauración intermedios en una transacción sin necesidad de abortar todo el trabajo previo.
-- Si el paso siguiente falla:
ROLLBACK TO SAVEPOINT punto_seguro;
COMMIT; -- Se guardan los pasos anteriores al savepoint!