ProgramaciónIngeniero de Datos

Describa los principios de uso de los niveles de aislamiento de transacciones (isolation levels) en SQL y cómo elegir el nivel de aislamiento adecuado para la aplicación. Proporcione ejemplos de anomalías para cada nivel.

Supere entrevistas con el asistente de IA Hintsage

Respuesta

El aislamiento de transacciones afecta cómo las transacciones concurrentes ven los cambios entre sí. Es una parte importante de las propiedades ACID. En ANSI SQL hay cuatro niveles de aislamiento básicos:

  • READ UNCOMMITTED — Ve incluso los cambios no confirmados de otras transacciones (lecturas sucias, dirty reads).
  • READ COMMITTED — Ve solo los cambios confirmados; previene lecturas sucias, pero permite lecturas no repetibles (non-repeatable reads).
  • REPEATABLE READ — Los mismos datos en una transacción se ven de manera inmutable. Evita lecturas sucias y no repetibles, pero puede haber lecturas fantasma (phantom reads).
  • SERIALIZABLE — El más estricto, las transacciones están completamente aisladas, como si se ejecutaran en secuencia; elimina todos los tipos de anomalías.

La elección del nivel depende de los requisitos de la aplicación:

  • Para informes, a menudo es suficiente con REPEATABLE READ o superior;
  • Para sistemas de alta carga, el compromiso óptimo es READ COMMITTED;
  • Para financiero — SERIALIZABLE, a pesar de la disminución en el rendimiento.

Ejemplo:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; -- Las siguientes SELECT verán valores "congelados"

Pregunta capciosa

"¿Garantiza el nivel REPEATABLE READ la protección contra lecturas fantasma en cualquier base de datos?"

No. En PostgreSQL y algunas otras bases de datos, el nivel REPEATABLE READ solo previene lecturas sucias y no repetibles, pero no necesariamente protege contra lecturas fantasma. En MySQL/InnoDB, REPEATABLE READ es esencialmente SERIALIZABLE, pero en otras bases de datos — no.

Ejemplo:
-- En una transacción leemos SELECT * FROM orders WHERE amount > 100; -- En otra transacción se inserta un nuevo valor con amount > 100 y se confirma -- La primera transacción al volver a hacer SELECT verá una fila "fantasma" si el aislamiento es inferior a SERIALIZABLE

Ejemplos de errores reales debido a la falta de conocimiento sobre los matices del tema


Historia

Un servicio financiero bloqueó solo READ COMMITTED por razones de rendimiento — el usuario vio un monto que ya había sido modificado por otro proceso, aparecieron discrepancias en el saldo.


Historia

En un sistema de reservas de hoteles se produjeron reservas dobles de la misma habitación — las transacciones no aislaron la descarga de reservas actuales, el nivel era READ COMMITTED.


Historia

Transición de MySQL a PostgreSQL: el desarrollador estaba acostumbrado a que REPEATABLE READ protegiera contra fantasmas, pero tras la migración aparecieron pedidos "atrapados" que no se esperaban al realizar consultas repetidas en la misma transacción.