Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Trigger und Tabellensperre in MySQL

Ich denke, der beste Weg, dies zu handhaben, wäre die Verwendung des hier beschriebenen SELECT ... FOR UPDATE-Musters:http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

Als Referenz:

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

...

In Ihrem Fall würden Sie also

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

Mit so etwas wie

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

Ich sage "so etwas wie", weil mir nicht ganz klar ist, worauf OLD.RuleId und OLD.IsResolved verweisen. Auch erwähnenswert von http://dev.mysql .com/doc/refman/5.0/en/innodb-locking-reads.html ist:

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

Mit anderen Worten, Sie können dieses Muster wahrscheinlich weiter optimieren, indem Sie nur einmal auf die Tabelle zugreifen ... aber auch hier gibt es einige Details zu Ihrem Schema, denen ich nicht ganz folge, und ich bin mir nicht sicher, ob ich die eigentliche Aussage liefern könnte d brauchen. Ich denke, wenn Sie einen Blick auf SELECT ... FOR UPDATE werfen, werden Sie sehen, worauf das Muster hinausläuft und was Sie tun müssen, damit dies in Ihrer Umgebung funktioniert.

Ich sollte auch erwähnen, dass es einige Speicher-Engine-Umgebungen und Transaktionsisolationsstufen gibt, die Sie berücksichtigen sollten. Es gibt hier eine sehr, sehr gute Diskussion über SO zu diesem Thema:Wann sollte SELECT ... FOR UPDATE verwendet werden?

Hoffe, das hilft!