SELECT FOR UPDATE obtém um bloqueio exclusivo de intenção na tabela antes de obter o bloqueio exclusivo no registro. Portanto, neste cenário:
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`
ocorre um deadlock, pois ambas as transações estão mantendo um
IX trava na mesa e esperando por um X bloqueio nos registros. Na verdade, esse mesmo cenário é descrito no
MySQL manual de travamento
. Para contornar isso, você precisa se livrar de todos os índices, exceto aquele em que você está pesquisando, que é
lock_name . Basta soltar a chave primária em
id .