SELECT FOR UPDATE
получава ексклузивно заключване с намерение на масата, преди да получи изключителното заключване на записа.
Следователно, в този сценарий:
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`
възниква безизходица, тъй като и двете транзакции съдържат IX
заключвам на масата и чакам X
заключете записите.
Всъщност този сценарий е описан в MySQL
ръководство за заключване
.
За да заобиколите това, трябва да се отървете от всички индекси с изключение на този, в който търсите, тоест lock_name
.
Просто пуснете първичния ключ в id
.