SELECT FOR UPDATE
obtient un verrou exclusif d'intention sur la table avant d'obtenir le verrou exclusif sur l'enregistrement.
Par conséquent, dans ce scénario :
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`
un interblocage se produit, car les deux transactions contiennent un IX
verrou sur la table et en attente d'un X
verrouiller les enregistrements.
En fait, ce scénario même est décrit dans le MySQL
manuel de verrouillage
.
Pour contourner ce problème, vous devez vous débarrasser de tous les index sauf celui sur lequel vous recherchez, c'est-à-dire lock_name
.
Déposez simplement la clé primaire sur id
.