J'ai une procédure stockée générant des UID d'une table "billet", mais sous charge, je reçois beaucoup d'impasse. J'appelle cette procédure plusieurs fois à partir de plusieurs connexions simultanentes chaque fois que ma tâche a besoin d'une nouvelle UID.
... ... dozens and dozens of the following record locks... Record lock, heap no 1046 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 0: len 1; hex 61; asc a;; 1: len 8; hex 00000000000335f2; asc 5 ;; Record lock, heap no 1047 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 0: len 1; hex 61; asc a;; 1: len 8; hex 00000000000335f1; asc 5 ;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 13 page no 4 n bits 1120 index `stub` of table `my_db`.`uid_data` trx id 13AA89 lock_mode X waiting Record lock, heap no 583 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 0: len 1; hex 61; asc a;; 1: len 8; hex 00000000000334a8; asc 4 ;; *** WE ROLL BACK TRANSACTION (1)
3 Réponses :
Une impasse survient dans ce scénario:
transaction 1: demande une serrure ( transaction 2: demande une serrure ( transaction 1: essaie d'insérer, hits un duplicaté, donc des mises à jour ( [modifier] une impasse se produit même avec:
P> Sélectionnez ... pour la mise à jour code>) et l'acquiert p>
Sélectionnez ... pour la mise à jour code>) et doit attendre p>
insert ... sur la mise à jour de la clé en double code>) => Deadlock P>
Je ne suis pas trop sûr de la raison, je soupçonne que cela a quelque chose à voir avec le sur la mise à jour de clé en double code>. Je cherche toujours et reviendrai si je découvre.
frappe> p>
BEGIN
START TRANSACTION;
UPDATE uid_data SET uid = uid +1;
SELECT uid FROM uid_data;
COMMIT;
END
Est-ce que cette procédure stockée révisée gère la concurrence avec un type de verrouillage?
@Senche oui, update code> est atomique, et il verrouille également la ou les lignes jusqu'à la fin de la transaction. Cependant, je suis toujours très curieux de la raison de la serrure morte dans votre séquence d'origine (voir aussi mes commentaires à votre question).
Vous pouvez essayer d'utiliser sur une table comme p> ceci est en sécurité et ne verrouille pas la table s'il est Myisam (sauf lors de la déclaration de mise à jour réelle). P> p>
fais cela: puis pour obtenir le prochain UID: p> série UID est équivalent à p> uid BIGINT(20) UNSIGNED NOT NULL PRIMARY KEY auto_increment
Je devrais ajouter de la clarté, que le last_insert_id () est une portée restreinte - par ex. Si 1000 de ces requêtes fonctionnent simultanément, il n'ya jamais de risque de ne pas avoir le mauvais numéro pour une connexion différente.
Pour plus d'informations: l'impasse se produit même lors de l'utilisation de cette séquence simple:
Démarrer la transaction; Sélectionnez UID à partir de UID_DATA pour la mise à jour; Mettre à jour Uid_Data Set Uid = UID +1 [[impasse possible ici]]; Commettre; code> (par conséquent, il n'a rien à voir avec le
sur la clause code> Duplicate). Cependant, aucune impasse ne se produit avec un niveau d'isolement de
lecture répétable; code>. Je ne sais toujours pas quoi conclure de ce point.