6
votes

MySQL Deadlocks avec procédure stockée générant UID

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)


1 commentaires

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; (par conséquent, il n'a rien à voir avec le sur la clause Duplicate). Cependant, aucune impasse ne se produit avec un niveau d'isolement de lecture répétable; . Je ne sais toujours pas quoi conclure de ce point.


3 Réponses :


0
votes

Une impasse survient dans ce scénario:

transaction 1: demande une serrure ( Sélectionnez ... pour la mise à jour code>) et l'acquiert p>

transaction 2: demande une serrure ( Sélectionnez ... pour la mise à jour code>) et doit attendre p>

transaction 1: essaie d'insérer, hits un duplicaté, donc des mises à jour ( 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>

[modifier] une impasse se produit même avec: P>

BEGIN
    START TRANSACTION;    
    UPDATE uid_data SET uid = uid +1;
    SELECT uid FROM uid_data;
    COMMIT;
END


2 commentaires

Est-ce que cette procédure stockée révisée gère la concurrence avec un type de verrouillage?


@Senche oui, update 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).



0
votes

Vous pouvez essayer d'utiliser xxx

sur une table comme xxx

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).


0 commentaires

2
votes

fais cela: xxx pré>

puis pour obtenir le prochain UID: p> xxx pré>

série UID est équivalent à p>

uid BIGINT(20) UNSIGNED NOT NULL PRIMARY KEY auto_increment


1 commentaires

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.