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 .