ProgramaciónDesarrollador Backend

Hable detalladamente sobre la especificidad del trabajo con transacciones en SQL. ¿Cómo controlar la integridad de los datos al acceder simultáneamente a una misma tabla desde diferentes sesiones?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

En SQL, las transacciones permiten agrupar varias operaciones (insert/update/delete) en una única unidad de trabajo atómica que se puede aplicar completamente o revertir. El ciclo de vida de una transacción se basa en los comandos:

  • BEGIN o START TRANSACTION — inicio de la transacción;
  • COMMIT — confirmación de cambios;
  • ROLLBACK — reversión de todos los cambios dentro de la transacción.

SQL soporta niveles de aislamiento de transacciones (Read Uncommitted, Read Committed, Repeatable Read, Serializable), que determinan la visibilidad de los datos entre transacciones paralelas y protegen contra problemas como "lecturas sucias" o "filas fantasma".

Para controlar la integridad de los datos se requiere:

  • Elección del nivel de aislamiento (por ejemplo, para aplicaciones bancarias — probablemente, Serializable).
  • Gestión explícita de transacciones, especialmente donde una entidad se edita simultáneamente (por ejemplo, SELECT ... FOR UPDATE).

Ejemplo en PostgreSQL:

BEGIN; -- Obtener y bloquear la fila del producto SELECT * FROM inventory WHERE id = 1 FOR UPDATE; UPDATE inventory SET quantity = quantity - 1 WHERE id = 1; COMMIT;

Pregunta capciosa

¿Qué nivel de aislamiento está establecido por defecto en los sistemas de base de datos populares (PostgreSQL, MySQL) y en qué se diferencia de SERIALIZABLE?

Respuesta:
En PostgreSQL, el nivel por defecto es Read Committed — en este, la transacción ve solo los datos confirmados en el momento de la consulta, pero pueden ocurrir "lecturas no repetibles".
En MySQL (InnoDB) — Repeatable Read. La diferencia con Serializable es que solo este último previene completamente cualquier cambio fantasma o paralelo, pero funciona significativamente más lento debido a bloqueos globales.

Ejemplo:

-- En Repeatable Read, SELECT puede devolver las mismas filas, mientras que en Read Committed pueden aparecer nuevas entre dos SELECT dentro de la transacción.

Historia

En un gran sistema financiero, durante transferencias masivas entre cuentas, con un bajo nivel de aislamiento (Read Committed), periódicamente se presentaban situaciones en las que un mismo saldo era utilizado simultáneamente por varias transacciones. Esto resultaba en un gasto duplicado de fondos (race condition). Después de pasar a Serializable y gestionar adecuadamente los bloqueos, el problema desapareció.


Historia

En comercio electrónico, una transacción con UPDATE product SET stock = stock - 1 sin envolverla en una transacción resultaba en la venta de más productos de los que había en stock. El problema solo se detectó con un gran número de pedidos concurrentes. La solución fue usar transacciones y bloqueo de filas a través de SELECT ... FOR UPDATE.


Historia

En un sistema logístico, en una de las tablas, durante actualizaciones frecuentes, se olvidaron del compromiso explícito. En caso de fallos, parte de los datos se perdía debido al autocommit o un rollback incorrecto. El resultado fue la pérdida de registros y una auditoría costosa.