Мисля, че най-добрият начин да се справите с това би бил да използвате шаблона SELECT ... FOR UPDATE, описан тук:http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
За справка:
SELECT counter_field FROM child_codes FOR UPDATE; UPDATE child_codes
SET counter_field = counter_field + 1;
...
Така че във вашия случай бихте заменили
LOCK TABLES AlarmCount WRITE, AlarmMembership READ;
UPDATE AlarmCount SET num = num - 1
WHERE RuleId = OLD.RuleId AND
MemberId = 0 AND
IsResolved = OLD.IsResolved;
С нещо като
SELECT num FROM AlarmCount WHERE RuleId = OLD.RuleId AND
MemberId = 0 AND
IsResolved = OLD.IsResolved FOR UPDATE;
UPDATE AlarmCount SET num = num - 1;
Казвам "нещо като", защото не ми е съвсем ясно какво препращат OLD.RuleId и OLD.IsResolved. Също така си струва да се отбележи от http://dev.mysql .com/doc/refman/5.0/en/innodb-locking-reads.html е:
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field +
1);
SELECT LAST_INSERT_ID();
С други думи, вероятно можете да оптимизирате този модел допълнително, като получите достъп до таблицата само веднъж... но отново има някои подробности за вашата схема, които не следвам съвсем и не съм сигурен, че мога да предоставя действителното изявление, което вие д трябва. Мисля обаче, че ако погледнете ИЗБЕРЕТЕ ... ЗА АКТУАЛИЗИРАНЕ, ще видите до какво се свежда моделът и какво трябва да направите, за да работи това във вашата среда.
Трябва също така да спомена, че има някои нива на среда за съхранение и нива на изолация на транзакциите, които бихте искали да вземете предвид. Има много, много добра дискусия относно SO по тази тема тук:Кога да използвате ИЗБОР ... ЗА АКТУАЛИЗИРАНЕ?
Надявам се това да помогне!