sql >> Databasteknik >  >> RDS >> Mysql

Hur låses innodb-tabeller när ON INSERT-utlösaren bearbetas?

Om samtidighetsproblemen har du en 'lätt' sätt att förhindra eventuella samtidighetsproblem i den andra metoden, gör en markering i din transaktion på artikelraden (For update är nu implicit). Alla samtidiga inlägg på samma artikel kommer inte att kunna få samma lås och väntar på dig.

Med de nya standardisoleringsnivåerna, utan att ens använda serialiseringsnivån i transaktionen, skulle du inte se någon samtidig infogning på röstbordet förrän i slutet av din transaktion. Så din SUMMA bör förbli sammanhängande eller ser ut som sammanhängande . Men om en samtidig transaktion lägger in en röst på samma artikel och begår före dig (och den här 2:a inte ser din bilaga), kommer den sista transaktionen att begå att skriva över räknaren och du förlorar 1 röst. Så utför ett radlås på artikeln genom att använda ett val innan (och gör ditt arbete i en transaktion, naturligtvis). Det är enkelt att testa, öppna 2 interaktiva sessioner på MySQL och starta transaktioner med BEGIN.

Om du använder triggern är du i en transaktion som standard. Men jag tycker att du bör utföra valet i artikeltabellen lika bra för att göra ett implicit radlås för samtidiga triggers som körs (svårare att testa).

  • Glöm inte att ta bort utlösare.
  • Glöm inte uppdateringsutlösare.
  • Om du inte använder triggers och stayin-kod, var noga med att varje infoga/ta bort/uppdatera fråga om röstning ska utföra en radlåsning på motsvarande artikel innan i transaktionen. Det är inte särskilt svårt att glömma en.

Sista punkten:gör svårare transaktioner, innan du startar transaktionen använd:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

På så sätt behöver du inte radlås på artiklar, MySQL kommer att upptäcka att en potentiell skrivning på samma rad inträffar och blockerar de andras transaktioner tills du är klar. Men använd inte något du har beräknat från en tidigare begäran . Uppdateringsfrågan väntar på en låsfrigivning för artiklar, när låset släpps av den första transaktionen COMMIT beräkningen av SUM bör göras igen för att räkna. Så uppdateringsfrågan bör innehålla SUM eller gör ett tillägg.

update articles set nb_votes=(SELECT count(*) from vote) where id=2; 

Och här ser du att MySQL är smart, ett dödläge upptäcks om 2 transaktioner försöker göra detta medan infogning har gjorts samtidigt. I serialiseringsnivåer har jag inte hittat något sätt att få ett felaktigt värde med :

   SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
   BEGIN;
       insert into vote (...
       update articles set nb_votes=(
         SELECT count(*) from vote where article_id=xx
       ) where id=XX;
    COMMIT;

Men var redo att hantera brytande transaktioner som du måste göra om.



  1. Hur man visar bild (bolb-typ) i jsp-sida från mySql DB i Struts 2 med Hibernate

  2. Hur man definierar unikt index på flera kolumner i uppföljning

  3. Mysql-kommandot hittades inte i OS X 10.7

  4. Uppdaterar vyer i MySQL