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
.