Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Gatilhos e bloqueio de tabela no MySQL


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!