CodeGym /Cursos /SQL SELF /Nivel de aislamiento READ COMMITTED

Nivel de aislamiento READ COMMITTED

SQL SELF
Nivel 40 , Lección 0
Disponible

Vamos a ver qué hace el nivel de aislamiento READ COMMITTED. Su nombre ya nos da una pista: todo lo que leemos dentro de una transacción ya está "commiteado" por otras transacciones. Es como en la vida real, solo creemos en los cotilleos que están oficialmente escritos en el acta.

En serio, este nivel garantiza que una transacción no puede ver los cambios hechos por otras transacciones que aún no han sido confirmados. Esto resuelve el problema conocido como "lectura sucia" (Dirty Read). Pero ojo, los datos que lees pueden cambiar si otra transacción hace commit entre tus consultas. Esto crea el riesgo de "lectura no repetible" (Non-Repeatable Read).

En PostgreSQL el nivel de aislamiento READ COMMITTED viene por defecto. Es como el modo default — no tienes que configurar nada especial para usarlo.

Ejemplo de uso del nivel de aislamiento READ COMMITTED

Vamos a ver cómo funciona en la práctica. Imagina que tenemos una tabla accounts con info de usuarios y sus balances:

CREATE TABLE accounts (
    account_id SERIAL PRIMARY KEY,
    account_name TEXT NOT NULL,
    balance NUMERIC(10, 2) NOT NULL
);

INSERT INTO accounts (account_name, balance)
VALUES ('Alice', 1000.00), ('Bob', 500.00);

Ahora imagina la siguiente situación. Sesión 1 y Sesión 2 — los dos protagonistas de nuestra historia, ambos trabajando con la tabla accounts. Esto es lo que pasa:

Sesión 1:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_name = 'Alice';
-- Ningún COMMIT ni ROLLBACK todavía.

En este momento, a balance de Alice se le han restado 100 temporalmente, pero el resultado aún no está confirmado.

Sesión 2:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

BEGIN;
SELECT balance FROM accounts WHERE account_name = 'Alice';

Resultado: Sesión 2 ve el balance de Alice como 1000.00, porque la transacción de la Sesión 1 aún no ha terminado (COMMIT no ejecutado). El nivel READ COMMITTED nos protege de la "lectura sucia".

Sesión 1 termina la transacción:

COMMIT;

Ahora el balance de Alice está actualizado y el valor 900.00 está guardado en la base de datos.

Sesión 2 repite la consulta:

SELECT balance FROM accounts WHERE account_name = 'Alice';

Resultado: ahora la Sesión 2 ve el balance actualizado de Alice — 900.00. Fíjate que el resultado es diferente al de la consulta anterior, que devolvía 1000.00. Esto es el problema de la "lectura no repetible".

¿Cuándo usar READ COMMITTED?

El nivel de aislamiento READ COMMITTED es un equilibrio entre rendimiento y consistencia. Pero hay algunos escenarios donde encaja perfecto:

  1. Operaciones CRUD simples: cuando solo lees o actualizas datos sin relaciones complejas.

  2. Actualización de registros: por ejemplo, actualizaciones masivas en una tabla donde es importante ver los cambios confirmados al instante.

  3. Procesamiento de transacciones: sistemas de pago donde los usuarios solo pueden ver datos confirmados.

Pero si haces consultas analíticas complejas o trabajas con grandes volúmenes de datos, quizá te convenga otro nivel de aislamiento, como REPEATABLE READ.

Ventajas y desventajas del nivel de aislamiento READ COMMITTED

El nivel de aislamiento READ COMMITTED es como el punto medio. Te protege de datos sucios: no verás cambios que otra transacción empezó pero aún no terminó. O sea, nadie leerá información "cruda" que podría ser revertida enseguida.

Este modo es más rápido que los niveles más estrictos (REPEATABLE READ o SERIALIZABLE), porque no necesita bloqueos complejos ni comprobaciones extra. Es bastante ligero y, a la vez, fiable — por eso se usa por defecto y va genial para la mayoría de tareas diarias.

Aunque previene la lectura sucia, READ COMMITTED no te protege de:

  • "Lectura no repetible" (Non-Repeatable Read): el valor de los datos puede cambiar si otra transacción hace cambios entre tus consultas.
  • "Lectura fantasma" (Phantom Read): otra transacción puede añadir filas que afectan el resultado de tu consulta.

Consejos al trabajar con READ COMMITTED

Siempre termina tus transacciones: no olvides usar COMMIT o ROLLBACK, si no puedes tener problemas de bloqueos.

Asegúrate de que el nivel de aislamiento es suficiente: si necesitas garantizar que los datos no cambian durante la transacción, considera REPEATABLE READ.

Usa índices: esto ayuda a PostgreSQL a encontrar datos y aplicar cambios más rápido.

Ejemplo: procesamiento de pedidos

Supón que tenemos una tabla orders donde se guardan los datos de los pedidos:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_name TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'pending'
);

INSERT INTO orders (customer_name, status)
VALUES ('Alice', 'pending'), ('Bob', 'pending');

Queremos actualizar el estado de los pedidos que están en estado "pending":

BEGIN;
SELECT * FROM orders WHERE status = 'pending';
UPDATE orders SET status = 'completed' WHERE status = 'pending';
COMMIT;

Si durante la ejecución otra transacción añade un nuevo pedido con estado "pending" y hace COMMIT, nuestra transacción no tendrá en cuenta esa fila, porque fue añadida después de empezar la lectura.

Esto es un ejemplo de "lectura fantasma". Si quieres evitar estas situaciones, tienes que usar SERIALIZABLE.

El nivel de aislamiento READ COMMITTED es la opción por defecto en la mayoría de bases de datos, incluyendo PostgreSQL. Te protege de lecturas sucias, lo que lo hace una buena opción para la mayoría de operaciones estándar. Pero en escenarios que requieren consistencia estricta, puede que necesites niveles de aislamiento más fuertes. La elección del nivel de aislamiento debe depender de tus tareas concretas y los requisitos de rendimiento.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION