sql >> Database >  >> RDS >> Mysql

Triggers en tafelvergrendeling in MySQL

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

. vervangen
LOCK 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!




  1. RANK, DENSE_RANK en ROW_NUMBER functies in Oracle

  2. Hoe zoek ik naar schuine streep (\) in MySQL? en waarom is escapen (\) niet vereist voor waar (=) maar voor Like is vereist?

  3. ROWIDTOCHAR() Functie in Oracle

  4. Oracle SQL unieke beperking A naar B, B naar A