Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Bloqueio morto do MySQL InnoDB em SELECT com bloqueio exclusivo (FOR UPDATE)


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 .