Ik denk dat de beste manier om dit aan te pakken zou zijn om het patroon SELECT ... FOR UPDATE te gebruiken dat hier wordt beschreven:http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
Ter referentie:
SELECT counter_field FROM child_codes FOR UPDATE; UPDATE child_codes
SET counter_field = counter_field + 1;
...
Dus in jouw geval zou je
. vervangenLOCK TABLES AlarmCount WRITE, AlarmMembership READ;
UPDATE AlarmCount SET num = num - 1
WHERE RuleId = OLD.RuleId AND
MemberId = 0 AND
IsResolved = OLD.IsResolved;
Met zoiets als
SELECT num FROM AlarmCount WHERE RuleId = OLD.RuleId AND
MemberId = 0 AND
IsResolved = OLD.IsResolved FOR UPDATE;
UPDATE AlarmCount SET num = num - 1;
Ik zeg "zoiets als" omdat het mij niet helemaal duidelijk is waarnaar OLD.RuleId en OLD.IsResolved verwijzen. Ook vermeldenswaard van http://dev.mysql .com/doc/refman/5.0/en/innodb-locking-reads.html is:
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field +
1);
SELECT LAST_INSERT_ID();
Met andere woorden, je kunt dit patroon waarschijnlijk verder optimaliseren door de tabel maar één keer te openen... d nodig. Ik denk echter dat als je een kijkje neemt SELECT ... FOR UPDATE, je zult zien waar het patroon op neerkomt en wat je moet doen om dit in je omgeving te laten werken.
Ik moet ook vermelden dat er een aantal opslagengine-omgevingen en transactie-isolatieniveaus zijn die u in overweging wilt nemen. Er is hier een zeer goede discussie over SO over dit onderwerp:Wanneer SELECT... VOOR UPDATE gebruiken?
Ik hoop dat dit helpt!