PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Blokada i transakcja w postgresie, która powinna blokować zapytanie

Opisane zachowanie jest normalne i oczekiwane w każdej transakcyjnej relacyjnej bazie danych.

Jeśli PostgreSQL pokazał ci wartość edited dla pierwszego SELECT byłoby to niewłaściwe – nazywa się to „brudnym odczytem” i jest złą wiadomością w bazach danych.

PostgreSQL będzie mógł czekać przy SELECT do czasu zatwierdzenia lub wycofania, ale nie jest to wymagane przez standard SQL, nie powiedziałeś, że chcesz czekać i nie musi czekać z żadnego powodu technicznego, więc zwraca dane, o które prosiłeś do natychmiastowego. W końcu, dopóki nie zostanie zatwierdzony, ta update istnieje tylko pewien rodzaj - nadal może się zdarzyć lub nie.

Jeśli PostgreSQL zawsze tu czekał, to szybko znalazłbyś się w sytuacji, w której tylko jedno połączenie może robić cokolwiek z bazą danych na raz. Niezbyt dobre dla wydajności i przez większość czasu całkowicie niepotrzebne.

Jeśli chcesz poczekać na jednoczesną UPDATE (lub DELETE ), użyjesz SELECT ... FOR SHARE . (Ale pamiętaj, że to nie zadziała w przypadku INSERT ).

Szczegóły:

SELECT bez FOR UPDATE lub FOR SHARE klauzula nie przyjmuje żadnych blokad na poziomie wiersza. Tak więc widzi to, co jest bieżącym zatwierdzonym wierszem i nie ma na niego wpływu żadne transakcje w locie, które mogą modyfikować ten wiersz. Koncepcje są wyjaśnione w sekcji MVCC dokumentacji . Ogólna idea jest taka, że ​​PostgreSQL działa w trybie kopiowania przy zapisie, z wersjonowaniem, które pozwala mu zwrócić poprawną kopię na podstawie tego, co transakcja lub instrukcja mogła „widzieć” w momencie jej uruchomienia – co PostgreSQL nazywa „migawką”.

W domyślnym READ COMMITTED migawki izolacji są wykonywane na poziomie instrukcji, więc jeśli SELECT wiersz, COMMIT zmiana w nim z innej transakcji i SELECT ponownie zobaczysz różne wartości nawet w ramach jednej transakcji. Możesz użyć SNAPSHOT izolacja, jeśli nie chcesz widzieć zmian zatwierdzonych po rozpoczęciu transakcji, lub SERIALIZABLE izolacja, aby dodać dalszą ochronę przed pewnymi rodzajami wzajemnych zależności transakcji.

Zobacz rozdział dotyczący izolacji transakcji w dokumentacji .

Jeśli chcesz SELECT aby czekać na zatwierdzenie lub wycofanie zmian w wybranych wierszach na transakcje w toku, należy użyć SELECT ... FOR SHARE . To zablokuje blokadę pobraną przez UPDATE lub DELETE dopóki transakcja, która spowodowała blokadę, nie zostanie wycofana lub zatwierdzona.

INSERT jest jednak inny - krotki po prostu nie istnieją dla innych transakcji do czasu zatwierdzenia. Jedyny sposób oczekiwania na równoczesne INSERT s to wziąć EXCLUSIVE blokada na poziomie tabeli, dzięki czemu wiesz, że nikt inny nie zmienia tabeli podczas jej czytania. Zwykle taka potrzeba oznacza jednak, że masz problem z projektowaniem aplikacji — Twoja aplikacja nie powinna się przejmować jeśli istnieją niezatwierdzone insert nadal w locie.

Zobacz rozdział dotyczący jawnego blokowania w dokumentacji .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zapisz dane wyjściowe PL/pgSQL z PostgreSQL do pliku CSV

  2. Dlaczego PostgreSQL niewłaściwie łączy serie?

  3. Pakiet pg nodejs powoduje „nieprawidłową składnię wejściową dla typu json”

  4. Jak utworzyć funkcję zdefiniowaną przez użytkownika w AWS Aurora RDS Postgres?

  5. Postgres nie używa indeksu w tablicy liczb całkowitych, jeśli jest zainstalowane rozszerzenie intarray