SELECT FOR UPDATE uzyskuje zamierzoną blokadę na wyłączność na stole przed uzyskaniem blokady na wyłączność na rekordzie.
Dlatego w tym scenariuszu:
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`
następuje zakleszczenie, ponieważ obie transakcje zawierają IX zablokować na stole i czekać na X zablokować zapisy.
Właściwie ten sam scenariusz jest opisany w MySQL instrukcja blokowania
.
Aby obejść ten problem, musisz pozbyć się wszystkich indeksów z wyjątkiem tego, którego szukasz, czyli lock_name .
Po prostu upuść klucz podstawowy na id .