SELECT FOR UPDATE
obtiene un bloqueo exclusivo de intención en la tabla antes de obtener el bloqueo exclusivo en el registro.
Por lo tanto, en este escenario:
X1: SELECT FOR UPDATE -- holds IX, holds X on 'lock_name'
X2: SELECT FOR UPDATE -- holds IX, waits for X on 'lock_name'
X1: INSERT -- holds IX, waits for X for the gap on `id`
se produce un interbloqueo, ya que ambas transacciones tienen un IX
bloqueo en la mesa y esperando una X
bloquear los registros.
En realidad, este mismo escenario se describe en el MySQL
manual de bloqueo
.
Para evitar esto, debe deshacerse de todos los índices excepto el que está buscando, que es lock_name
.
Simplemente suelte la clave principal en id
.