Rozumiem różnice między optymistycznym a pesymistycznym blokowaniem. Czy ktoś mógłby mi teraz wyjaśnić, kiedy używałbym jednego z nich w ogóle?
I czy odpowiedź na to pytanie zmienia się w zależności od tego, czy do wykonania zapytania używam procedury składowanej?
Ale tylko dla sprawdzenia, optymizm oznacza „nie blokuj stołu podczas czytania”, a pesymistyczny oznacza „blokuj stół podczas czytania”.
sql-server
locking
optimistic-locking
pessimistic-locking
Jason Baker
źródło
źródło
At any technique type conflicts should be detected and considered, with similar overhead for both materialized and non-materialized conflicts
.Odpowiedzi:
Optymistyczne blokowanie to strategia polegająca na czytaniu rekordu, zapisywaniu numeru wersji (inne metody do tego celu obejmują daty, znaczniki czasu lub sumy kontrolne / skróty) i sprawdzaniu, czy wersja nie uległa zmianie przed ponownym zapisaniem rekordu. Kiedy zapisujesz rekord z powrotem, filtrujesz aktualizację do wersji, aby upewnić się, że jest atomowa. (tzn. nie został zaktualizowany między sprawdzeniem wersji i zapisaniem rekordu na dysku) a aktualizacją wersji za jednym razem.
Jeśli zapis jest brudny (tzn. Inna wersja niż Twoja), przerywasz transakcję, a użytkownik może ją ponownie uruchomić.
Strategia ta ma największe zastosowanie do systemów o dużej objętości i architektur trójwarstwowych, w których niekoniecznie utrzymuje się połączenie z bazą danych dla sesji. W tej sytuacji klient nie może faktycznie utrzymywać blokad bazy danych, ponieważ połączenia są pobierane z puli i możesz nie używać tego samego połączenia z jednego dostępu do drugiego.
Blokowanie pesymistyczne ma miejsce, gdy blokujesz rekord na wyłączny użytek, dopóki go nie skończysz. Ma znacznie lepszą integralność niż optymistyczne blokowanie, ale wymaga ostrożności podczas projektowania aplikacji, aby uniknąć Deadlocks . Aby użyć blokowania pesymistycznego, potrzebujesz albo bezpośredniego połączenia z bazą danych (jak to zwykle bywa w przypadku dwupoziomowej aplikacji serwera klienta ), albo dostępnego z zewnątrz identyfikatora transakcji, którego można używać niezależnie od połączenia.
W tym ostatnim przypadku otwierasz transakcję za pomocą TxID, a następnie ponownie łączysz się przy użyciu tego identyfikatora. DBMS utrzymuje blokady i pozwala wybrać sesję z powrotem poprzez TxID. Tak działają transakcje rozproszone z wykorzystaniem protokołów zatwierdzania dwufazowego (takich jak Transakcje XA lub COM + ).
źródło
Blokowanie optymistyczne jest stosowane, gdy nie spodziewasz się wielu kolizji. Wykonanie normalnej operacji kosztuje mniej, ale jeśli zdarzy się kolizja, zapłacisz wyższą cenę za jej rozwiązanie, gdy transakcja zostanie przerwana.
Blokowanie pesymistyczne jest stosowane, gdy przewiduje się kolizję. Transakcje, które naruszałyby synchronizację, są po prostu blokowane.
Aby wybrać odpowiedni mechanizm blokujący, musisz oszacować ilość odczytów i zapisów oraz odpowiednio zaplanować.
źródło
Optymistycznie zakłada, że podczas czytania nic się nie zmieni.
Pesymizm zakłada, że coś się stanie i dlatego to blokuje.
Jeśli dane nie są idealnie odczytywane, użyj optymizmu. Możesz dostać dziwny „brudny” odczyt - ale znacznie mniej prawdopodobne jest, że doprowadzi to do impasu i tym podobnych.
Większość aplikacji internetowych jest w porządku z brudnymi odczytami - w rzadkich przypadkach dane nie zgadzają się dokładnie przy następnym przeładowaniu.
Do dokładnych operacji na danych (jak w wielu transakcjach finansowych) używaj pesymizmu. Ważne jest, aby dane były dokładnie odczytywane, bez żadnych niewyświetlanych zmian - dodatkowy koszt blokowania jest tego wart.
Aha, a Microsoft SQL Server domyślnie blokuje strony - w zasadzie wiersz, który czytasz i kilka po obu stronach. Blokowanie wierszy jest dokładniejsze, ale znacznie wolniejsze. Często warto ustawić transakcje na zatwierdzone do odczytu lub bez blokady, aby uniknąć zakleszczeń podczas czytania.
źródło
Oprócz tego, co już powiedziano:
optimistic
blokowanie ma tendencję do poprawy współbieżności kosztem przewidywalności.Pessimistic
blokowanie ma tendencję do zmniejszania współbieżności, ale jest bardziej przewidywalne. Płacisz pieniądze itp.źródło
W przypadku konfliktów masz dwie opcje:
Teraz rozważmy następującą anomalię utraconej aktualizacji :
Anomalia utraconej aktualizacji może wystąpić na poziomie izolacji Read Committed .
Na powyższym schemacie możemy zobaczyć, że Alice wierzy, że może wypłacić 40,
account
ale nie zdaje sobie sprawy, że Bob właśnie zmienił saldo konta, a teraz na koncie pozostało tylko 20.Blokowanie pesymistyczne
Blokowanie pesymistyczne osiąga ten cel, biorąc na koncie blokadę współdzieloną lub blokadę odczytu, dzięki czemu Bob nie może zmienić konta.
Na powyższym schemacie zarówno Alice, jak i Bob uzyskają blokadę odczytu w
account
wierszu tabeli, którą przeczytali obaj użytkownicy. Baza danych nabywa te blokady na SQL Server, gdy używa się powtarzalnego odczytu lub szeregowego.Ponieważ zarówno Alice, jak i Bob odczytali
account
wartość PK1
, żaden z nich nie może jej zmienić, dopóki jeden użytkownik nie zwolni blokady odczytu. Wynika to z faktu, że operacja zapisu wymaga akwizycji blokad zapisu / wyłączności, a blokady współdzielone / odczytu zapobiegają blokowaniu zapisu / wyłączności.Dopiero po zatwierdzeniu transakcji przez Alicję i zwolnieniu blokady odczytu w
account
wierszu, BobUPDATE
wznowi i zastosuje zmianę. Dopóki Alice nie zwolni blokady odczytu, UPDATE Boba blokuje.Optymistyczne blokowanie
Optymistyczne blokowanie pozwala na wystąpienie konfliktu, ale wykrywa go po zastosowaniu AKTUALIZACJI Alicji po zmianie wersji.
Tym razem mamy dodatkową
version
kolumnę.version
Kolumna jest zwiększany za każdym razem, aktualizacji lub usuwania jest wykonywana, a to jest również wykorzystywane w klauzuli WHERE w UPDATE i DELETE. Aby to zadziałało, musimy wydać WYBIERZ i odczytać prądversion
przed wykonaniem UPDATE lub DELETE, ponieważ w przeciwnym razie nie wiedzielibyśmy, jaką wartość wersji przekazać do klauzuli WHERE lub zwiększyć.Transakcje na poziomie aplikacji
Systemy relacyjnych baz danych pojawiły się pod koniec lat 70. na początku lat 80., gdy klient zazwyczaj łączył się z komputerem mainframe za pośrednictwem terminala. Dlatego wciąż widzimy, że systemy baz danych definiują terminy, takie jak ustawienie SESSION.
Obecnie przez Internet nie wykonujemy już operacji odczytu i zapisu w kontekście tej samej transakcji z bazą danych, a ACID nie jest już wystarczający.
Rozważmy na przykład następujący przypadek użycia:
Bez optymistycznego blokowania nie ma szans na złapanie tej Utraconej aktualizacji, nawet jeśli transakcje bazy danych wykorzystywałyby Serializable. Wynika to z tego, że odczyty i zapisy są wykonywane w osobnych żądaniach HTTP, a więc w różnych transakcjach w bazie danych.
Tak więc optymistyczne blokowanie może pomóc w zapobieganiu Utraconym aktualizacjom nawet podczas korzystania z transakcji na poziomie aplikacji, które uwzględniają również czas myślenia użytkownika.
Wniosek
Blokowanie optymistyczne jest bardzo przydatną techniką i działa dobrze nawet przy użyciu mniej rygorystycznych poziomów izolacji, takich jak odczyt zatwierdzony lub gdy odczyty i zapisy są wykonywane w kolejnych transakcjach bazy danych.
Wadą optymistycznego blokowania jest to, że ramy dostępu do danych będą wyzwalane po złapaniu
OptimisticLockException
, a zatem utracie całej pracy, którą wykonaliśmy poprzednio przez aktualnie wykonywaną transakcję.Im więcej sporów, tym więcej konfliktów i większa szansa na przerwanie transakcji. Wycofanie może być kosztowne dla systemu bazy danych, ponieważ musi on cofnąć wszystkie bieżące oczekujące zmiany, które mogą obejmować zarówno wiersze tabeli, jak i rekordy indeksu.
Z tego powodu pesymistyczne blokowanie może być odpowiednie w przypadku częstych konfliktów, ponieważ zmniejsza ryzyko wycofania transakcji.
źródło
PESSIMISTIC_FORCE_INCREMENT
.Pomyślałbym o jeszcze jednym przypadku, w którym pesymistyczne zamknięcie byłoby lepszym wyborem.
Aby uzyskać optymistyczne blokowanie, każdy uczestnik modyfikacji danych musi wyrazić zgodę na stosowanie tego rodzaju blokowania. Ale jeśli ktoś zmodyfikuje dane bez dbania o kolumnę wersji, zepsuje to cały pomysł optymistycznego blokowania.
źródło
Istnieją w zasadzie dwie najpopularniejsze odpowiedzi. Pierwsza w zasadzie mówi
Inną odpowiedzią jest
lub
Jak to jest umieszczone na tej stronie.
Stworzyłem swoją odpowiedź, aby wyjaśnić, w jaki sposób „zachowaj połączenie” odnosi się do „niskich kolizji”.
Aby zrozumieć, która strategia jest dla Ciebie najlepsza, nie myśl o transakcjach na sekundę, które ma Twój DB, ale o czasie trwania pojedynczej transakcji. Zwykle otwierasz transakcję, wykonujesz operację i zamykasz transakcję. Jest to krótka, klasyczna transakcja, o której pomyślała ANSI, i dobrze jest uciec od blokady. Ale jak wdrożyć system rezerwacji biletów, w którym wielu klientów rezerwuje te same pokoje / miejsca w tym samym czasie?
Przeglądasz oferty, wypełniasz formularz z wieloma dostępnymi opcjami i aktualnymi cenami. Zajmuje to dużo czasu, a opcje mogą stać się nieaktualne, wszystkie niepoprawne ceny między tobą zaczęły wypełniać formularz i nacisnąć przycisk „Zgadzam się”, ponieważ nie było blokady danych, do których masz dostęp, i ktoś inny, bardziej zwinny, interferował zmieniając wszystkie ceny i musisz zacząć od nowa z nowymi cenami.
Zamiast tego możesz zablokować wszystkie opcje podczas ich czytania. To jest scenariusz pesymistyczny. Widzisz, dlaczego to jest do bani. Twój system może zostać zniszczony przez jednego klauna, który po prostu rozpoczyna rezerwację i pali papierosy. Nikt nie może nic zarezerwować, dopóki nie skończy. Twoje przepływy pieniężne spadają do zera. Dlatego w rzeczywistości wykorzystywane są optymistyczne rezerwacje. Ci, którzy zbyt długo marudzą, muszą wznowić rezerwację po wyższych cenach.
W tym optymistycznym podejściu musisz zapisać wszystkie dane, które czytasz (jak w moim powtórnym czytaniu ) i dojść do punktu zatwierdzenia z twoją wersją danych (chcę kupić akcje po cenie wyświetlonej w tym cenniku, a nie bieżącej cenie ). W tym momencie tworzona jest transakcja ANSI, która blokuje DB, sprawdza, czy nic się nie zmienia i zatwierdza / przerywa operację. IMO, jest to skuteczna emulacja MVCC , która jest również powiązana z Optimistic CC i zakłada również, że twoja transakcja uruchomi się ponownie w przypadku przerwania, to znaczy, że dokonasz nowej rezerwacji. Transakcja dotyczy tutaj decyzji użytkownika.
Daleki jestem od zrozumienia, jak ręcznie wdrożyć MVCC, ale myślę, że długoterminowe transakcje z opcją ponownego uruchomienia są kluczem do zrozumienia tematu. Popraw mnie, jeśli gdziekolwiek się mylę. Moja odpowiedź była motywowana tym rozdziałem Alexa Kuznecowa .
źródło
W większości przypadków optymistyczne blokowanie jest bardziej wydajne i oferuje wyższą wydajność. Wybierając między blokowaniem pesymistycznym a optymistycznym, weź pod uwagę następujące kwestie:
Blokowanie pesymistyczne jest przydatne, jeśli istnieje wiele aktualizacji i stosunkowo duże szanse, że użytkownicy spróbują zaktualizować dane w tym samym czasie. Na przykład, jeśli każda operacja może aktualizować dużą liczbę rekordów jednocześnie (bank może dodawać zyski odsetkowe do każdego konta na koniec każdego miesiąca), a dwie aplikacje uruchamiają takie operacje w tym samym czasie, będą miały konflikty .
Blokowanie pesymistyczne jest również bardziej odpowiednie w aplikacjach, które zawierają często aktualizowane tabele. W przypadku tak zwanych punktów aktywnych konflikty są tak prawdopodobne, że optymistyczne blokowanie marnuje wysiłek w wycofywaniu sprzecznych transakcji.
Optymistyczne blokowanie jest przydatne, gdy prawdopodobieństwo wystąpienia konfliktów jest bardzo niskie - istnieje wiele rekordów, ale stosunkowo niewielu użytkowników lub bardzo mało aktualizacji i głównie operacje typu do odczytu.
źródło
Jednym z przypadków użycia optymistycznego blokowania jest użycie aplikacji przez bazę danych, aby umożliwić jednemu z twoich wątków / hostów „zajęcie” zadania. Jest to technika, która regularnie mi się przydaje.
Najlepszym przykładem, jaki mogę wymyślić, jest kolejka zadań zaimplementowana przy użyciu bazy danych, przy czym wiele wątków jednocześnie wykonuje zadania. Jeśli zadanie ma status „Dostępne”, „Zgłoszone”, „Ukończone”, zapytanie bazy danych może powiedzieć coś w rodzaju „Ustaw status =„ Zgłoszony ”gdzie status =„ Dostępny ”. Jeśli wiele wątków próbuje zmienić status w ten sposób, wszystko oprócz pierwszego wątku zawiedzie z powodu brudnych danych.
Zauważ, że jest to przypadek użycia obejmujący tylko optymistyczne blokowanie. Alternatywnie do powiedzenia „Optymistyczne blokowanie jest stosowane, gdy nie spodziewasz się wielu kolizji”, może być również stosowane tam, gdzie oczekujesz kolizji, ale chcesz, aby dokładnie jedna transakcja zakończyła się powodzeniem.
źródło
Wiele dobrych rzeczy zostało powiedzianych powyżej o optymistycznym i pesymistycznym blokowaniu. Ważną kwestią do rozważenia jest:
Korzystając z optymistycznego blokowania, musimy zachować ostrożność, ponieważ w jaki sposób aplikacja będzie mogła odzyskać te błędy.
Szczególnie w przypadku architektur opartych na komunikatach asynchronicznych może to prowadzić do przetwarzania komunikatów poza kolejnością lub utraty aktualizacji.
Scenariusze awarii należy przemyśleć.
źródło