0Pricing
SQL Academy · Lección

Interbloqueos: detección y prevención

Comprenda cómo se producen los interbloqueos, cómo los detecta Postgres y diseñe reglas de ordenación de bloqueos que los eviten.

Interbloqueos: detección y prevención es una lección gratuita de SQL Academy 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 SQL Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de SQL Academy incluye 4 lecciones en total.

¿Qué es un interbloqueo?

Dos transacciones tienen cada una un bloqueo que la otra necesita; ninguna puede continuar. La base de datos detecta el ciclo y aborta una de las transacciones.

Un interbloqueo clásico

La transacción A bloquea la fila 1 y la transacción B bloquea la fila 2. A solicita la fila 2 y B solicita la fila 1. Se quedan bloqueadas.

-- Tx A:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- waiting for B...

-- Tx B:
BEGIN;
UPDATE accounts SET balance = balance - 50 WHERE id = 2;
UPDATE accounts SET balance = balance + 50 WHERE id = 1;
-- waiting for A...

-- ERROR: deadlock detected

PostgreSQL detecta los interbloqueos

Cada deadlock_timeout (1 segundo de forma predeterminada), PostgreSQL comprueba si hay ciclos de bloqueos. Si encuentra uno, aborta una transacción con el código de error 40P01.

ERROR:  deadlock detected
DETAIL:  Process 1234 waits for ShareLock on transaction 5678 ...

Regla de orden de los bloqueos

La solución: adquiera siempre los bloqueos en el mismo orden en todas las rutas del código.

-- Always update the lower id first:
UPDATE accounts SET balance = balance - 100 WHERE id = LEAST(:from, :to);
UPDATE accounts SET balance = balance + 100 WHERE id = GREATEST(:from, :to);

Interbloqueos en filas muy solicitadas

Las actualizaciones rápidas de las mismas filas muy solicitadas suelen provocar esperas por bloqueos, no interbloqueos. Utilice colas, particione la fila muy solicitada o serialice las actualizaciones en el código de la aplicación.

FOR UPDATE bloquea las filas leídas

Adquiera bloqueos de escritura al leer para evitar sorpresas más adelante:

BEGIN;
SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
-- both rows locked in id order
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

Omitir filas bloqueadas

Para tablas de colas, utilice el patrón «tomar cualquier fila disponible»:

SELECT * FROM jobs
WHERE status = 'pending'
ORDER BY created_at
LIMIT 1
FOR UPDATE SKIP LOCKED;
-- skips rows other workers have locked

NOWAIT

Falle inmediatamente en lugar de esperar:

SELECT * FROM accounts WHERE id = 1 FOR UPDATE NOWAIT;
-- ERROR: could not obtain lock on row in relation "accounts"

Diagnóstico de interbloqueos

Aumente log_lock_waits y capture el contexto del interbloqueo en el registro. La entrada del registro muestra ambas transacciones y sus consultas.

Bucle de reintento en la aplicación

Los interbloqueos se pueden resolver: vuelva a intentar la transacción abortada:

for (let attempt = 0; attempt < 3; attempt++) {
  try {
    await runTransaction();
    break;
  } catch (e) {
    if (e.code === '40P01') continue;     // deadlock
    throw e;
  }
}

Reducir el alcance de los bloqueos

Acorte las transacciones: cada fila afectada permanece bloqueada hasta COMMIT. No realice llamadas HTTP ni cálculos largos dentro de una transacción.

Indexar las claves foráneas para evitar la escalada de bloqueos

Al eliminar un elemento principal, se comprueba cada fila secundaria. Sin un índice en la FK, eso implica un escaneo completo de la tabla Y bloqueos de filas. Indexe cada columna FK.

Resumen

Los interbloqueos ocurren; diseñe el sistema para minimizarlos.

  • Adquiera los bloqueos en un orden coherente
  • Utilice FOR UPDATE pronto para declarar la intención
  • Utilice SKIP LOCKED para las colas
  • Reintente cuando se produzcan errores de interbloqueo (40P01)
  • Mantenga cortas las transacciones

Comprobación rápida

¿Cuál es el principio de diseño más fiable para evitar interbloqueos?

Preguntas frecuentes

¿La lección «Interbloqueos: detección y prevención» es gratis?

Sí — el texto completo de «Interbloqueos: detección y prevención» 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 SQL Academy, actualiza a CoddyKit PRO. El curso de SQL Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Interbloqueos: detección y prevención»?

Comprenda cómo se producen los interbloqueos, cómo los detecta Postgres y diseñe reglas de ordenación de bloqueos que los eviten. Practicas SQL Academy 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 SQL Academy?

No se requiere experiencia previa. SQL Academy 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 «Interbloqueos: detección y prevención»?

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 SQL Academy?

Sí. Cada lección de SQL Academy 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

  1. Propiedades ACID y anomalías
  2. Niveles de aislamiento: READ COMMITTED, REPEATABLE READ, SERIALIZABLE
  3. Interbloqueos: detección y prevención
  4. Bloqueo optimista frente a pesimista
← Volver a SQL Academy