PostgreSQL jest wyposażony w solidne, sprawdzone funkcje, które pozwalają dokładnie zdefiniować, co powinno się stać, gdy wielu klientów próbuje jednocześnie aktualizować te same dane. Jednym z nich jest poziom izolacji transakcji.
Czytaj dalej, aby dowiedzieć się więcej o tym, jak działa izolacja transakcji w PostgreSQL.
Transakcje i poziom izolacji
Transakcje są podstawowym sposobem mutowania danych w RDBMS. Nowoczesne RDBMS pozwalają na równoczesne uruchamianie więcej niż jednej transakcji, a co za tym idzie są dostarczane z różnymi narzędziami – niektórymi standardowymi, niektórymi specyficznymi dla RDBMS – dla programistów aplikacji, aby określić, w jaki sposób ich transakcje powinny lub nie powinny wchodzić w interakcje z innymi transakcjami.
Poziomy izolacji transakcji i pesymistyczne blokady to dwa takie narzędzia. Chociaż są one niezbędne do zapewnienia integralności danych i wydajności, niestety nie są intuicyjne w zrozumieniu ani użyciu.
Poziom izolacji transakcji w PostgreSQL może być jednym z:
- Przeczytaj zatwierdzone
- Powtarzalny odczyt
- Możliwość serializacji
Każda transakcja ma poziom izolacji ustawiony na jeden z tych, gdy jest tworzona. Domyślny poziom to „zatwierdzenie odczytu”.
Zwróć uwagę, że standard SQL definiuje również „odczyt niezatwierdzony”, co nie jest obsługiwane w Postgresie. Musisz użyć najbliższego, wyższego poziomu „zatwierdzonego odczytu”.
Zobaczmy, co oznaczają te poziomy.
Przeczytaj zatwierdzone
Co się dzieje, gdy jedna (niedokończona) transakcja wstawia wiersze do tabeli, a druga (również niedokończona) transakcja próbuje odczytać wszystkie wiersze w tabeli? Jeśli druga transakcja jest w stanie zobaczyć wiersze wstawione przez pierwszą, wtedy to read nazywa się brudnym odczytem – ponieważ pierwsza transakcja może zostać wycofana, a druga transakcja odczytałaby „fantomowe” wiersze, które nigdy nie istniały.
Czytanie popełnione poziom izolacji gwarantuje, że brudne odczyty nigdy się nie wydarzą. Oto przykład:
Jak widać, druga transakcja nie mogła odczytać danych jako-jeszcze niezatwierdzonych z pierwszej transakcji. W PostgreSQL nie jest możliwe obniżenie poziomu izolacji poniżej tego poziomu, aby umożliwić nieprawidłowe odczyty.
Powtarzalny odczyt
Jeszcze inny problem to niepowtarzalne odczyty. Dzieje się tak, gdy transakcja odczytuje wiersz, a następnie nieco później odczytuje go ponownie, ale otrzymuje inny wynik – ponieważ wiersz został zaktualizowany w międzyczasie przez inną transakcję. Odczyt stał się niepowtarzalny , jak pokazano w tym przykładzie:
Aby rozwiązać ten problem, ustaw poziom izolacji transakcji na „repeatableread”. PostgreSQL zapewni wtedy, że drugi (lub dowolny) odczyt również zwróci ten sam wynik, co pierwszy odczyt. Oto ten sam scenariusz na podwyższonym poziomie izolacji:
Zauważ, że poziom izolacji został określony wraz z instrukcją BEGIN. Możliwe jest również określenie tego na poziomie połączenia (jako parametr połączenia), jako parametr konfiguracyjny (default_transaction_isolation
) i za pomocą instrukcji SET TRANSACTION.
Możliwość serializacji
Następny poziom izolacji rozwiązuje problem utraconych aktualizacji . Aktualizacje wykonane w jednej transakcji mogą zostać „utracone” lub nadpisane przez inną transakcję, która przebiega równolegle, jak pokazano tutaj:
Tutaj bloki UPDATE drugiej transakcji, ponieważ PostgreSQL blokuje, aby zapobiec kolejnej aktualizacji, dopóki pierwsza transakcja nie zostanie zakończona. Jednak zmiana pierwszej transakcji zostaje utracona, ponieważ druga „nadpisała” wiersz.
Jeśli tego rodzaju zachowanie jest nie do zaakceptowania, możesz uaktualnić poziom izolacji na możliwy do serializacji:
Na tym poziomie zatwierdzenie drugiej transakcji kończy się niepowodzeniem. Działania drugiej transakcji były oparte na faktach, które zostały unieważnione w momencie, gdy miała zostać zatwierdzona.
Chociaż serializacja zapewnia najwyższy poziom bezpieczeństwa, oznacza to również, że aplikacja musi wykrywać takie niepowodzenia zatwierdzenia i ponawiać całą transakcję.