I PostgreSQL vil rækkerne blive låst, efterhånden som de opdateres -- faktisk er måden dette faktisk fungerer på, at hver tuple (version af en række) har et systemfelt kaldet xmin
for at angive, hvilken transaktion, der gjorde denne tuple aktuel (ved indsættelse eller opdatering) og et systemfelt kaldet xmax
for at angive, hvilken transaktion der udløb den tuple (ved opdatering eller sletning). Når du får adgang til data, tjekker den hver tuple for at afgøre, om den er synlig for din transaktion, ved at kontrollere dit aktive "snapshot" mod disse værdier.
Hvis du udfører en OPDATERING, og en tuple, der matcher dine søgebetingelser, har en xmin, som ville gøre den synlig for dit øjebliksbillede og en xmax af en aktiv transaktion, blokerer den og venter på, at transaktionen er fuldført. Hvis transaktionen, som først opdaterede tuplen, ruller tilbage, vågner din transaktion og behandler rækken; hvis den første transaktion forpligtes, vågner din transaktion op og skrider til handling afhængigt af det aktuelle transaktionsisoleringsniveau.
Det er klart, at et dødvande er resultatet af, at dette sker for rækker i anden rækkefølge. Der er ingen række-niveau lås i RAM, som kan fås for alle rækker på samme tid, men hvis rækker er opdateret i samme rækkefølge kan du ikke have den cirkulære låsning. Desværre er den foreslåede IN(1, 2)
syntaks garanterer ikke det. Forskellige sessioner kan have forskellige omkostningsfaktorer aktive, en baggrunds "analyse"-opgave kan ændre statistik for tabellen mellem generering af den ene plan og den anden, eller den kan bruge en seqscan og blive påvirket af PostgreSQL-optimeringen, som forårsager en ny seqscan at slutte sig til en allerede igangværende og "loop rundt" for at reducere disk I/O.
Hvis du laver opdateringerne én ad gangen i samme rækkefølge, i applikationskode eller ved hjælp af en markør, så vil du kun have simpel blokering, ikke deadlocks. Generelt er relationsdatabaser dog tilbøjelige til serialiseringsfejl, og det er bedst at få adgang til dem gennem en ramme, som genkender dem baseret på SQLSTATE og automatisk gentager hele transaktionen fra starten. I PostgreSQL vil en serialiseringsfejl altid have en SQLSTATE på 40001 eller 40P01.
http://www.postgresql.org/docs/current/interactive/mvcc-intro.html