sql >> Databasteknik >  >> RDS >> PostgreSQL

postgresql dödläge

Det här är två kommentarer som infogas med samma content_id. Att bara infoga kommentaren kommer att ta ut ett DELA-lås på innehållsraden, för att förhindra att en annan transaktion tar bort den raden tills den första transaktionen har slutförts.

Utlösaren fortsätter dock sedan med att uppgradera låset till EXKLUSIVT, och detta kan blockeras av en samtidig transaktion som utför samma process. Tänk på följande händelseförlopp:

Txn 2754                      Txn 2053
Insert Comment
                              Insert Comment
Lock Content#935967 SHARE
  (performed by fkey)
                              Lock Content#935967 SHARE
                                (performed by fkey)
Trigger
Lock Content#935967 EXCLUSIVE
(blocks on 2053's share lock)
                              Trigger
                              Lock Content#935967 EXCLUSIVE
                              (blocks on 2754's share lock)

Så- dödläge.

En lösning är att omedelbart ta ett exklusivt lås på innehållsraden före infoga kommentaren. dvs.

SELECT 1 FROM content WHERE content.id = 935967 FOR UPDATE
INSERT INTO comment(.....)

En annan lösning är helt enkelt att undvika detta "cachade antal"-mönster helt, förutom där du kan bevisa att det är nödvändigt för prestanda. Om så är fallet, överväg att behålla det cachade antalet någon annanstans än innehållstabellen - t.ex. ett dedikerat bord för disken. Det kommer också att minska uppdateringstrafiken till innehållstabellen varje gång en kommentar läggs till. Eller kanske bara välj om räkningen och använd memcached i applikationen. Det går inte att komma runt det faktum att var du än lagrar detta cachade antal kommer att vara en chokepunkt, måste det uppdateras på ett säkert sätt.




  1. Sammanfoga två tabeller SQL

  2. Kan inte skapa MySQL TRIGGER när jag använder IS NOT NULL

  3. MySQL infogar inte ett snedstreck

  4. Hur beräknar man ett kolumnvärde i oracle 10g?