Puedes ejecutar cualquier consulta de concurrencia en nuestra consola interactiva: Abrir consola SQL →
Bloqueos y concurrencia en SQL: control de acceso simultáneo
La concurrencia es uno de los temas más críticos en bases de datos. SQL utiliza bloqueos y niveles de aislamiento para evitar inconsistencias cuando múltiples usuarios acceden a los mismos datos.
Tabla de contenidos
1. Tipos de bloqueos
- Shared Lock (S) — permite lectura, bloquea escritura.
- Exclusive Lock (X) — bloquea lectura y escritura.
- Update Lock (U) — transición entre S y X.
- Intent Locks — bloqueos jerárquicos.
2. Bloqueos de lectura y escritura
-- Lectura con bloqueo compartido
SELECT * FROM cuentas WITH (HOLDLOCK);
-- Escritura con bloqueo exclusivo
UPDATE cuentas SET saldo = saldo + 100 WHERE id = 1;
3. Niveles de aislamiento
- READ UNCOMMITTED — permite lecturas sucias.
- READ COMMITTED — evita lecturas sucias.
- REPEATABLE READ — evita lecturas no repetibles.
- SERIALIZABLE — máximo aislamiento.
- SNAPSHOT — versiones de datos sin bloqueos.
4. Problemas de concurrencia
- Dirty Read — leer datos no confirmados.
- Non‑repeatable Read — datos cambian entre lecturas.
- Phantom Read — nuevas filas aparecen en una segunda lectura.
- Deadlocks — dos transacciones se bloquean mutuamente.
5. Soluciones
- Elegir el nivel de aislamiento adecuado.
- Evitar transacciones largas.
- Acceder a tablas en el mismo orden.
- Usar índices para reducir bloqueos.
- Utilizar SNAPSHOT para evitar bloqueos.
6. Ejemplos prácticos
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;
SELECT * FROM cuentas WHERE id = 1;
UPDATE cuentas SET saldo = saldo - 50 WHERE id = 1;
COMMIT;
-- Evitar deadlocks
BEGIN;
UPDATE cuentas SET saldo = saldo - 10 WHERE id = 1;
UPDATE cuentas SET saldo = saldo + 10 WHERE id = 2;
COMMIT;
7. Ejercicios para practicar
- Simula un deadlock.
- Usa READ COMMITTED para evitar lecturas sucias.
- Prueba SNAPSHOT para evitar bloqueos.
- Identifica un phantom read.
- Explica la diferencia entre S y X locks.
-- Deadlock
BEGIN;
UPDATE cuentas SET saldo = saldo - 10 WHERE id = 1;
-- Otra transacción bloquea id=2
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT * FROM cuentas;
ALTER DATABASE miapp SET ALLOW_SNAPSHOT_ISOLATION ON;
-- Phantom read: nuevas filas aparecen en una segunda lectura
-- S permite lectura; X bloquea todo.
8. Mini‑proyecto: Sistema bancario concurrente
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
SELECT saldo FROM cuentas WHERE id = 10;
UPDATE cuentas SET saldo = saldo - 200 WHERE id = 10;
COMMIT;
9. Errores comunes
- Usar SERIALIZABLE sin necesidad.
- Transacciones demasiado largas.
- No manejar deadlocks.
- No usar índices en tablas concurridas.
10. Preguntas frecuentes
¿Los bloqueos siempre son malos?
No, garantizan integridad.
¿SNAPSHOT elimina todos los bloqueos?
Evita muchos, pero no todos.