Acho que a melhor maneira de lidar com isso seria usar o padrão SELECT ... FOR UPDATE descrito aqui:http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
Para referência:
SELECT counter_field FROM child_codes FOR UPDATE; UPDATE child_codes
SET counter_field = counter_field + 1;
...
Então, no seu caso, você substituiria
LOCK TABLES AlarmCount WRITE, AlarmMembership READ;
UPDATE AlarmCount SET num = num - 1
WHERE RuleId = OLD.RuleId AND
MemberId = 0 AND
IsResolved = OLD.IsResolved;
Com algo como
SELECT num FROM AlarmCount WHERE RuleId = OLD.RuleId AND
MemberId = 0 AND
IsResolved = OLD.IsResolved FOR UPDATE;
UPDATE AlarmCount SET num = num - 1;
Digo "algo como" porque não está totalmente claro para mim o que OLD.RuleId e OLD.IsResolved estão fazendo referência. Também digno de nota de 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();
Em outras palavras, você provavelmente pode otimizar ainda mais esse padrão acessando a tabela apenas uma vez... preciso. Eu acho que se você der uma olhada em SELECT ... FOR UPDATE, no entanto, você verá no que o padrão se resume e o que você precisa fazer para que isso funcione em seu ambiente.
Devo mencionar também que existem alguns níveis de isolamento de transação e ambiente de mecanismo de armazenamento que você deve considerar. Há uma discussão muito, muito boa sobre SO sobre este tópico aqui:Quando usar SELECT ... FOR UPDATE?
Espero que isto ajude!