El bloqueo (locking) en MySQL controla el acceso concurrente a los datos, evitando problemas como lecturas inconsistentes, actualizaciones concurrentes y condiciones de carrera. MySQL maneja dos tipos principales de bloqueos:
Es el tipo de bloqueo más simple y se aplica a toda la tabla cuando se realizan operaciones de lectura o escritura.
🔹 Tipos de bloqueo de tabla en MySQL:
READ LOCK
(Bloqueo de lectura)
LOCK TABLES nombre_tabla READ;
WRITE LOCK
(Bloqueo de escritura)
LOCK TABLES nombre_tabla WRITE;
🔹 Ejemplo de bloqueo de tabla:
LOCK TABLES pedidos READ;
SELECT * FROM pedidos; -- Otras sesiones pueden leer pero no escribir
UNLOCK TABLES; -- Libera el bloqueo
LOCK TABLES pedidos WRITE;
UPDATE pedidos SET estado = 'Enviado' WHERE id_pedido = 1; -- Exclusivo
UNLOCK TABLES; -- Libera el bloqueo
💡 Desventaja: Puede reducir la concurrencia si varias sesiones intentan acceder a la misma tabla.
MySQL usa bloqueos a nivel de fila cuando se trabaja con InnoDB, lo que permite mayor concurrencia.
🔹 Cómo se activan los bloqueos de fila en MySQL:
SELECT ... FOR UPDATE
→ Bloquea las filas seleccionadas para evitar que otras transacciones las modifiquen.SELECT ... LOCK IN SHARE MODE
→ Permite que otras transacciones lean las filas, pero impide modificaciones hasta que se libere el bloqueo.🔹 Ejemplo de SELECT ... FOR UPDATE
:
START TRANSACTION;
SELECT saldo FROM cuentas WHERE id_cuenta = 1 FOR UPDATE;
-- Otra transacción no podrá modificar la cuenta hasta que se haga COMMIT o ROLLBACK
UPDATE cuentas SET saldo = saldo - 100 WHERE id_cuenta = 1;
COMMIT;
💡 Útil en transacciones bancarias para evitar condiciones de carrera.
🔹 Ejemplo de SELECT ... LOCK IN SHARE MODE
:
START TRANSACTION;
SELECT * FROM productos WHERE id_producto = 1 LOCK IN SHARE MODE;
-- Permite que otros lean el dato, pero bloquea modificaciones
COMMIT;
✅ Ventaja: Mayor concurrencia que el bloqueo de tabla.
❌ Desventaja: Puede generar deadlocks si varias transacciones bloquean diferentes filas y esperan desbloqueos.
MySQL aplica bloqueos automáticos dependiendo del motor de almacenamiento:
🔹 En MyISAM:
SELECT
puede ejecutarse mientras no haya una operación de escritura en curso.INSERT
, UPDATE
o DELETE
bloquea la tabla para otros procesos.🔹 En InnoDB:
Un deadlock ocurre cuando dos transacciones bloquean recursos que la otra necesita, generando un ciclo infinito.
🔹 Cómo evitar deadlocks:
LOCK IN SHARE MODE
en lugar de FOR UPDATE
si solo necesitas leer.NOWAIT
o SKIP LOCKED
para evitar esperas innecesarias.🔹 Ejemplo con NOWAIT
para evitar esperar bloqueos:
SELECT * FROM productos WHERE id_producto = 1 FOR UPDATE NOWAIT;
💡 Si la fila ya está bloqueada, la consulta falla en lugar de esperar.
🔹 Ejemplo con SKIP LOCKED
para evitar filas bloqueadas:
SELECT * FROM pedidos WHERE estado = 'Pendiente' FOR UPDATE SKIP LOCKED;
💡 Selecciona solo filas no bloqueadas, evitando que la consulta se detenga.
✅ Usa InnoDB para mejor concurrencia con bloqueos de fila.
✅ Usa FOR UPDATE
solo cuando sea necesario para evitar bloqueos innecesarios.
✅ Usa LOCK IN SHARE MODE
para lecturas concurrentes sin bloqueos exclusivos.
✅ Mantén las transacciones cortas para minimizar bloqueos y mejorar el rendimiento.
✅ Ordena el acceso a tablas y registros de manera consistente para reducir deadlocks.