Lecturas sucias, no repetibles y fantasma
Las tres anomalías de lectura y qué nivel de aislamiento evita cada una.
Lecturas sucias, no repetibles y fantasma es una lección gratuita de Coding Interview Prep en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Coding Interview Prep, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Coding Interview Prep incluye 4 lecciones en total.
Las tres anomalías de lectura
Los niveles de aislamiento existen para evitar errores de concurrencia específicos llamados anomalías de lectura. En las entrevistas se espera que defina las tres con precisión y relacione cada una con el nivel que la evita.
- Lectura sucia: leer datos no confirmados
- Lectura no repetible: una fila cambia entre dos lecturas
- Lectura fantasma: aparecen filas nuevas entre dos lecturas
La dificultad está en distinguir una lectura no repetible de una lectura fantasma, porque ambas implican volver a consultar y obtener resultados diferentes.
Lectura sucia: definición
Una lectura sucia ocurre cuando la transacción T1 lee una fila que la transacción T2 ha modificado, pero que todavía no ha confirmado. Si T2 revierte los cambios, T1 habrá actuado sobre datos que en realidad nunca existieron.
Solo READ UNCOMMITTED permite lecturas sucias. Todos los niveles superiores las prohíben.
Peligro en el mundo real: aprobar un préstamo basándose en un depósito que se revierte unos segundos después.
Lectura sucia: línea de tiempo
Lea las dos columnas como una línea de tiempo. T1 se ejecuta con READ UNCOMMITTED.
T1 ve un saldo de 700, pero T2 nunca confirma la transacción. Los 700 eran un espejismo producido por el trabajo en curso de T2. Después de que T2 revierta los cambios, el valor real sigue siendo 500. T1 tomó una decisión basándose en datos basura.
-- T2 (not committed) | -- T1 (READ UNCOMMITTED)
BEGIN; |
UPDATE accounts |
SET balance = 700 |
WHERE id = 1; |
| SELECT balance FROM accounts
| WHERE id = 1; -- reads 700 (dirty!)
ROLLBACK; |
| -- T1 acted on a value that never existedLectura no repetible: definición
Una lectura no repetible ocurre cuando T1 lee una fila, T2 confirma una actualización o eliminación de esa misma fila, y T1 vuelve a leerla y observa un valor diferente.
Observe la diferencia clave respecto a una lectura sucia: aquí T2 ha confirmado la transacción. Los datos son reales, pero cambiaron mientras T1 los utilizaba dentro de una misma transacción.
READ COMMITTED todavía permite este fenómeno. REPEATABLE READ y los niveles superiores lo evitan leyendo desde una instantánea estable.
Lectura no repetible: línea de tiempo
T1 se ejecuta con READ COMMITTED y lee la misma fila dos veces. Entre ambas lecturas, T2 confirma un cambio.
La misma clave primaria devuelve dos valores diferentes dentro de una sola transacción. Esta inconsistencia puede romper la lógica de varios pasos que supone que la fila es estable.
-- T1 (READ COMMITTED) | -- T2
BEGIN; |
SELECT balance FROM accounts |
WHERE id = 1; -- 500 |
| BEGIN;
| UPDATE accounts SET balance = 900
| WHERE id = 1;
| COMMIT;
SELECT balance FROM accounts |
WHERE id = 1; -- 900 (changed!) |
COMMIT; |Lectura fantasma: definición
Una lectura fantasma ocurre cuando T1 ejecuta una consulta con una condición de búsqueda, T2 confirma una operación INSERT (o DELETE) de filas que cumplen esa condición, y T1 vuelve a ejecutar la consulta y observa un conjunto de filas diferente.
La diferencia respecto a una lectura no repetible es la siguiente: una lectura no repetible trata del valor de una fila existente que cambia; una lectura fantasma trata del número de filas que cumplen un predicado, que cambia.
El estándar solo garantiza que SERIALIZABLE evita las lecturas fantasma.
Lectura fantasma: línea de tiempo
T1 cuenta dos veces las cuentas de alto valor. Entre ambos recuentos, T2 inserta una nueva fila que cumple la condición y confirma la transacción.
No cambió ninguna fila existente, pero el resultado de COUNT es diferente. La nueva fila es la «fantasma» que apareció en el conjunto de resultados de T1.
-- T1 (REPEATABLE READ, standard) | -- T2
BEGIN; |
SELECT COUNT(*) FROM accounts |
WHERE balance > 1000; -- 3 |
| INSERT INTO accounts(id, balance)
| VALUES (99, 5000);
| COMMIT;
SELECT COUNT(*) FROM accounts |
WHERE balance > 1000; -- 4 (phantom)|
COMMIT; |Relación entre anomalías y niveles
Esta relación es el núcleo del tema. Estos son los niveles más bajos que evitan cada anomalía:
- Lectura sucia: se evita desde
READ COMMITTEDen adelante. - Lectura no repetible: se evita desde
REPEATABLE READen adelante. - Lectura fantasma: se evita con
SERIALIZABLE(según el estándar).
Observe que los nombres encajan: REPEATABLE READ hace que las lecturas sean repetibles; los niveles reciben su nombre de la anomalía que corrigen por primera vez.
Lectura no repetible frente a lectura fantasma: la diferencia clave
Es la confusión más habitual en las entrevistas. Recuerde esta frase:
Lectura no repetible = cambió el valor de una fila existente. Lectura fantasma = cambió el conjunto de filas que cumplen la condición (se añadieron o eliminaron filas).
Póngase a prueba: T2 ejecuta UPDATE ... WHERE id = 5 y después confirma la transacción, y T1 vuelve a leer la fila 5. Eso es una lectura no repetible. T2 ejecuta INSERT para insertar una nueva fila que cumple el WHERE de T1, y T1 vuelve a ejecutar la consulta. Eso es una lectura fantasma.
Desviación de escritura: la anomalía adicional
En las entrevistas para puestos sénior pueden ir más allá de las tres anomalías estándar y preguntar por la desviación de escritura: dos transacciones leen conjuntos que se solapan, realizan escrituras distintas basándose en lo que han leído y ambas confirman la transacción, dejando un estado que ninguna habría permitido por sí sola.
Ejemplo clásico: hay dos médicos de guardia; cada uno comprueba que otro médico está de guardia y entonces se retira del turno. Ambos lo consiguen y dejan la cobertura en cero.
El aislamiento de instantáneas (REPEATABLE READ de Postgres) permite la desviación de escritura; solo SERIALIZABLE la evita. Mencionarlo demuestra conocimientos avanzados.
Actualización perdida: la cuarta trampa
En las entrevistas a veces introducen la actualización perdida, que no forma parte de la lista de anomalías del estándar, pero aparece constantemente en la práctica. Dos transacciones leen el mismo valor, ambas calculan un nuevo valor a partir de él y ambas lo escriben. La segunda escritura sobrescribe silenciosamente la primera.
Ejemplo: dos transferencias leen un saldo de 500, ambas restan una cantidad y ambas escriben su resultado. Una de las restas se pierde.
La solución no consiste simplemente en usar un nivel de aislamiento superior, sino en aplicar un bloqueo explícito con SELECT ... FOR UPDATE, o en realizar una actualización atómica que haga el cálculo en la base de datos en lugar de hacerlo en la aplicación.
-- Safe pattern: lock the row, or compute atomically
BEGIN;
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE; -- locks row
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;
-- Or simply: UPDATE accounts SET balance = balance - 100 WHERE id = 1;Comprobación rápida
Identifique la anomalía a partir de su comportamiento.
Repaso: anomalías y sus soluciones
Tres anomalías de lectura, cada una resuelta por un nivel de aislamiento superior:
- Lectura sucia (datos no confirmados): se resuelve con READ COMMITTED.
- Lectura no repetible (cambia el valor de una fila existente): se resuelve con REPEATABLE READ.
- Lectura fantasma (cambia el conjunto de filas coincidentes): se resuelve con SERIALIZABLE.
Mantenga clara la diferencia entre lectura no repetible y lectura fantasma, y mencione la desviación de escritura si el entrevistador quiere profundizar. A continuación veremos cómo los motores hacen cumplir realmente el aislamiento: bloqueos, interbloqueos y MVCC.
Preguntas frecuentes
¿La lección «Lecturas sucias, no repetibles y fantasma» es gratis?
Sí — el texto completo de «Lecturas sucias, no repetibles y fantasma» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Coding Interview Prep, actualiza a CoddyKit PRO. El curso de Coding Interview Prep incluye 4 lecciones en total.
¿Qué aprenderé en «Lecturas sucias, no repetibles y fantasma»?
Las tres anomalías de lectura y qué nivel de aislamiento evita cada una. Practicas Coding Interview Prep con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Coding Interview Prep?
No se requiere experiencia previa. Coding Interview Prep en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Lecturas sucias, no repetibles y fantasma»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Coding Interview Prep?
Sí. Cada lección de Coding Interview Prep incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Explicación de las propiedades ACID
- Los cuatro niveles de aislamiento
- Lecturas sucias, no repetibles y fantasma
- Interbloqueos, bloqueos y MVCC