sql >> Databasteknik >  >> RDS >> Mysql

Hur låser jag på en InnoDB-rad som inte finns ännu?

Även om svaret ovan är sant genom att ett VÄLJ ... FÖR UPPDATERING kommer att förhindra samtidiga sessioner/transaktioner från att infoga samma post, det är inte den fullständiga sanningen. Jag kämpar för närvarande med samma problem och har kommit till slutsatsen att SELECT ... FOR UPDATE är nästan värdelös i den situationen av följande anledning:

En samtidig transaktion/session kan också göra ett VÄLJ ... FÖR UPPDATERING på samma post/indexvärde, och MySQL accepterar det gärna omedelbart (icke-blockerande) och utan att kasta fel. Naturligtvis, så snart den andra sessionen har gjort det, kan din session inte heller infoga posten längre. Varken din eller den andra sessionen/transaktionen får någon information om situationen och tror att de säkert kan infoga posten tills de faktiskt försöker göra det. Att försöka infoga leder sedan antingen till ett dödläge eller till ett duplicerat nyckelfel, beroende på omständigheterna.

Med andra ord, SELECT ... FOR UPDATE förhindrar andra sessioner från att infoga respektive post(er), MEN även om du gör en SELECT ... FOR UPDATE och respektive post inte hittas, är chansen stor att du faktiskt inte kan infoga den posten. IMHO, som gör metoden "först fråga, sedan infoga" värdelös.

Orsaken till problemet är att MySQL inte erbjuder någon metod för att på riktigt låsa obefintliga poster. Två samtidiga sessioner/transaktioner kan låsa obefintliga poster "FÖR UPPDATERING" samtidigt, något som egentligen inte borde vara möjligt och som försvårar utvecklingen betydligt.

Det enda sättet att kringgå detta verkar vara att använda semafortabeller eller att låsa hela tabellen vid insättning. Se MySQL-dokumentationen för ytterligare referens om att låsa hela tabeller eller använda semafortabeller.

Bara mina 2 cent ...



  1. Vad är MySQL? – En introduktion till databashanteringssystem

  2. Hur man distribuerar Open edX MySQL-databasen för hög tillgänglighet

  3. Node JS asynkrona databasanrop

  4. Ersätt standard nollvärden som returneras från vänster yttre sammanfogning