W PostgreSQL wiersze będą blokowane w miarę ich aktualizacji — w rzeczywistości działa to tak, że każda krotka (wersja wiersza) ma pole systemowe o nazwie xmin
aby wskazać, która transakcja uczyniła tę krotkę bieżącą (przez wstawienie lub aktualizację) oraz pole systemowe o nazwie xmax
aby wskazać, która transakcja wygasła w tej krotce (przez aktualizację lub usunięcie). Gdy uzyskujesz dostęp do danych, sprawdza każdą krotkę, aby określić, czy jest ona widoczna dla Twojej transakcji, porównując aktywną „migawkę” z tymi wartościami.
Jeśli wykonujesz UPDATE, a krotka, która pasuje do twoich warunków wyszukiwania, ma xmin, dzięki czemu jest widoczna dla twojego zrzutu i xmax aktywnej transakcji, blokuje się, czekając na zakończenie tej transakcji. Jeśli transakcja, która jako pierwsza zaktualizowała krotkę, zostanie wycofana, transakcja budzi się i przetwarza wiersz; jeśli pierwsza transakcja zostanie zatwierdzona, transakcja budzi się i podejmuje działania w zależności od aktualnego poziomu izolacji transakcji.
Oczywiście impas jest wynikiem tego, co dzieje się z rzędami w innej kolejności. W pamięci RAM nie ma blokady na poziomie wiersza, którą można uzyskać dla wszystkich wierszy w tym samym czasie, ale jeśli wiersze są aktualizowane w tej samej kolejności, nie można mieć blokady kołowej. Niestety sugerowany IN(1, 2)
składnia tego nie gwarantuje. Różne sesje mogą mieć aktywne różne współczynniki kosztów, zadanie "analizy" w tle może zmienić statystyki dla tabeli między generowaniem jednego planu a drugim lub może używać seqscan i być pod wpływem optymalizacji PostgreSQL, co powoduje nowy seqscan aby dołączyć do jednego, który jest już w toku i "zapętlić się", aby zredukować dyskowe I/O.
Jeśli będziesz wykonywać aktualizacje pojedynczo w tej samej kolejności, w kodzie aplikacji lub za pomocą kursora, będziesz miał tylko proste blokowanie, a nie zakleszczenia. Generalnie jednak relacyjne bazy danych są podatne na awarie serializacji i najlepiej jest uzyskać do nich dostęp za pośrednictwem frameworka, który rozpozna je na podstawie SQLSTATE i automatycznie ponawia całą transakcję od początku. W PostgreSQL błąd serializacji zawsze będzie miał stan SQLSTATE 40001 lub 40P01.
http://www.postgresql.org/docs/current/interactive/mvcc-intro.html