Myślę, że najlepszym sposobem na poradzenie sobie z tym byłoby użycie opisanego tutaj wzorca SELECT ... FOR UPDATE:http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
W celach informacyjnych:
SELECT counter_field FROM child_codes FOR UPDATE; UPDATE child_codes
SET counter_field = counter_field + 1;
...
Więc w twoim przypadku zamieniłbyś
LOCK TABLES AlarmCount WRITE, AlarmMembership READ;
UPDATE AlarmCount SET num = num - 1
WHERE RuleId = OLD.RuleId AND
MemberId = 0 AND
IsResolved = OLD.IsResolved;
Z czymś takim jak
SELECT num FROM AlarmCount WHERE RuleId = OLD.RuleId AND
MemberId = 0 AND
IsResolved = OLD.IsResolved FOR UPDATE;
UPDATE AlarmCount SET num = num - 1;
Mówię „coś takiego”, ponieważ nie jest dla mnie do końca jasne, do czego odwołuje się OLD.RuleId i OLD.IsResolved. Warto również zwrócić uwagę na http://dev.mysql .com/doc/refman/5.0/en/innodb-locking-reads.html jest:
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field +
1);
SELECT LAST_INSERT_ID();
Innymi słowy, prawdopodobnie możesz dalej zoptymalizować ten wzorzec, uzyskując dostęp do tabeli tylko raz ... ale znowu są pewne szczegóły dotyczące twojego schematu, których nie do końca śledzę i nie jestem pewien, czy mógłbym podać rzeczywiste oświadczenie, potrzebuję. Myślę, że jeśli spojrzysz na WYBIERZ ... DO AKTUALIZACJI, zobaczysz, do czego sprowadza się wzór i co musisz zrobić, aby działał w twoim środowisku.
Powinienem również wspomnieć, że istnieje kilka środowisk silnika pamięci masowej i poziomów izolacji transakcji, które warto wziąć pod uwagę. Na ten temat toczy się bardzo, bardzo dobra dyskusja na ten temat:Kiedy używać WYBIERZ... DO AKTUALIZACJI?
Mam nadzieję, że to pomoże!