Mysql
 sql >> Base de données >  >> RDS >> Mysql

Déclencheurs et verrouillage de table dans MySQL

Je pense que la meilleure façon de gérer cela serait d'utiliser le modèle SELECT ... FOR UPDATE décrit ici :http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

Pour référence :

 SELECT counter_field FROM child_codes FOR UPDATE; UPDATE child_codes
 SET counter_field = counter_field + 1; 

...

Donc dans votre cas, vous remplaceriez

LOCK TABLES AlarmCount WRITE, AlarmMembership READ;
  UPDATE AlarmCount SET num = num - 1 
  WHERE RuleId = OLD.RuleId AND
      MemberId = 0 AND
      IsResolved = OLD.IsResolved;

Avec quelque chose comme

SELECT num FROM AlarmCount WHERE RuleId = OLD.RuleId AND
          MemberId = 0 AND
          IsResolved = OLD.IsResolved FOR UPDATE;
UPDATE AlarmCount SET num = num - 1;

Je dis "quelque chose comme" parce que ce n'est pas tout à fait clair pour moi à quoi OLD.RuleId et OLD.IsResolved font référence. A noter également sur http://dev.mysql .com/doc/refman/5.0/en/innodb-locking-reads.html est :

UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field +
1); 
SELECT LAST_INSERT_ID();

En d'autres termes, vous pouvez probablement optimiser davantage ce modèle en n'accédant qu'une seule fois à la table ... mais encore une fois, il y a des détails sur votre schéma que je ne suis pas tout à fait, et je ne suis pas sûr de pouvoir fournir la déclaration réelle que vous ' d besoin. Je pense que si vous jetez un coup d'œil à SELECT ... FOR UPDATE, vous verrez à quoi se résume le modèle et ce que vous devez faire pour que cela fonctionne dans votre environnement.

Je dois également mentionner qu'il existe certains niveaux d'environnement de moteur de stockage et d'isolation des transactions que vous voudrez prendre en compte. Il y a une très, très bonne discussion sur SO sur ce sujet ici :Quand utiliser SELECT ... FOR UPDATE ?

J'espère que cela vous aidera !