Relacja poziomów izolacji transakcji z blokadami na stole

105

Przeczytałem o 4 poziomach izolacji:

Isolation Level       Dirty Read    Nonrepeatable Read  Phantom Read  
READ UNCOMMITTED      Permitted       Permitted           Permitted
READ COMMITTED              --        Permitted           Permitted
REPEATABLE READ             --             --             Permitted
SERIALIZABLE                --             --              --

Chcę zrozumieć blokadę, jaką przyjmuje każda izolacja transakcji na stole

READ UNCOMMITTED - no lock on table
READ COMMITTED - lock on committed data
REPEATABLE READ - lock on block of sql(which is selected by using select query)
SERIALIZABLE - lock on full table(on which Select query is fired)

poniżej przedstawiono trzy zjawiska, które mogą wystąpić w izolacji transakcji
Brudny odczyt - brak blokady
Niepowtarzalny odczyt - brak brudnego odczytu jako blokady zatwierdzonych danych
Odczyt fantomowy - blokada bloku sql (który jest wybierany przy użyciu zapytania wybierającego)

Chcę zrozumieć, gdzie definiujemy te poziomy izolacji: tylko na poziomie jdbc / hibernacji lub również w DB

PS: Przeszedłem przez linki w Poziomach izolacji w wyroczni , ale wyglądają niezgrabnie i mówią o specyficznych dla bazy danych

Uczeń
źródło
3
Zależy to całkowicie od bazy danych. Różne bazy danych mogą używać różnych algorytmów do określania poziomów izolacji. Niektórzy mogą używać MVCC (bez blokad w zapytaniach wybranych), inni używają ścisłego blokowania 2-fazowego (blokady współdzielone i wyłączne).
herbata brb

Odpowiedzi:

157

Chcę zrozumieć blokadę, jaką przyjmuje każda izolacja transakcji na stole

Na przykład masz 3 równoczesne procesy A, B i C. A rozpoczyna transakcję, zapisuje dane i zatwierdza / wycofuje (w zależności od wyników). B po prostu wykonuje SELECTpolecenie w celu odczytania danych. C czyta i aktualizuje dane. Wszystkie te procesy działają na tej samej tabeli T.

  • CZYTAJ NIEZGODNE - bez kłódki na stole. Możesz czytać dane w tabeli podczas pisania na niej. Oznacza to, że A zapisuje dane (niezatwierdzone), a B może odczytywać te niezatwierdzone dane i używać ich (w dowolnym celu). Jeśli A wykonuje wycofanie, B nadal odczytał dane i użył ich. Jest to najszybszy, ale najbardziej niebezpieczny sposób pracy z danymi, ponieważ może prowadzić do luk w danych w tabelach niezwiązanych fizycznie (tak, dwie tabele mogą być logicznie, ale nie fizycznie powiązane w rzeczywistych aplikacjach = \).
  • READ COMMITTED - zablokuj zatwierdzone dane. Możesz odczytać tylko dane, które zostały zatwierdzone. Oznacza to, że A zapisuje dane, a B nie może odczytać danych zapisanych przez A, dopóki A nie wykona zatwierdzenia. Problem polega na tym, że C może aktualizować dane, które były odczytywane i używane na kliencie B i B nie będą miały zaktualizowanych danych.
  • REPEATABLE READ - zablokuj blok SQL (który jest wybierany przy pomocy zapytania wybierającego). Oznacza to, że B odczytuje dane pod pewnymi warunkami, tj. WHERE aField > 10 AND aField < 20A wstawia dane, których aFieldwartość zawiera się między 10 a 20, a następnie B odczytuje dane ponownie i uzyskuje inny wynik.
  • SERIALIZABLE - blokada na pełnej tabeli (na której uruchamiane jest zapytanie Select). Oznacza to, że B czyta dane i żadna inna transakcja nie może modyfikować danych w tabeli. Jest to najbezpieczniejszy, ale najwolniejszy sposób pracy z danymi. Ponadto, ponieważ prosta operacja odczytu blokuje tabelę , może to prowadzić do poważnych problemów na produkcji: wyobraź sobie, że tabela T jest tabelą faktur, użytkownik X chce znać faktury z dnia, a użytkownik Y chce utworzyć nową fakturę, więc podczas gdy X odczytuje faktury, Y nie może dodać nowej faktury (a jeśli chodzi o pieniądze, ludzie naprawdę się wściekają, zwłaszcza szefowie).

Chcę zrozumieć, gdzie definiujemy te poziomy izolacji: tylko na poziomie JDBC / hibernacji lub również w DB

Używając JDBC, definiujesz go za pomocą Connection#setTransactionIsolation.

Korzystanie z hibernacji:

<property name="hibernate.connection.isolation">2</property>

Gdzie

  • 1: CZYTAJ NIEZGODNE
  • 2: PRZECZYTAJ ZATWIERDZONO
  • 4: POWTARZALNY ODCZYT
  • 8: SERIALIZOWALNY

Konfiguracja hibernacji jest pobierana stąd (przepraszam, jest w języku hiszpańskim).

Nawiasem mówiąc, możesz ustawić poziom izolacji również w RDBMS:

i tak dalej...

Luiggi Mendoza
źródło
docs.oracle.com/cd/B12037_01/server.101/b10743/consist.htm Tylko do dodania dla Oracle: można ustawić poziom izolacji transakcji, używając jednej z następujących instrukcji na początku transakcji: SET TRANSACTION ISOLATION ODCZYT POZIOMU ​​ZATWIERDZONY; USTAW SERIALIZOWALNY POZIOM IZOLACJI TRANSAKCJI; USTAW TYLKO ODCZYT TRANSAKCJI;
Learner
2
Ponadto, aby zaoszczędzić koszty sieci i przetwarzania związane z rozpoczęciem każdej transakcji za pomocą instrukcji SET TRANSACTION, można użyć instrukcji ALTER SESSION do ustawienia poziomu izolacji transakcji dla wszystkich kolejnych transakcji: ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE; ALTER SESSION SET ISOLATION_LEVEL READ COMMITTED;
Uczeń
12
Odnośnie REPEATABLE READ - myślę, że lepszym przykładem pokazującym to jest następujący: B rozpoczyna transakcję, odczytuje dane z bloku sql GDZIE aField> 10 AND aField <20, dane są zablokowane do zakończenia transakcji. A próbuje zaktualizować te dane, ale czeka z powodu blokady. Teraz, gdy B odczyta te dane ponownie w tej samej transakcji, gwarantuje to odczyt tych samych danych, ponieważ są one zablokowane. Popraw mnie, jeśli się mylę.
BornToCode
1
@LuiggiMendoza W ogólnym pojęciu, poziom izolacji tylko o Brudnym Przeczytaj , jednorazowych Przeczytaj i Wiersze Phantom . Zamki (S2PL) lub MVCC to implementacje dla różnych dostawców.
herbata brb
4
@LuiggiMendoza - nie byłem dokładny, powinno być tak - dane, które czytał B nie ulegają zmianie, ale konsekwentne selekcje dokonane przez B mogą zwrócić więcej wierszy. Dzieje się tak, ponieważ A nie może modyfikować wierszy, które B już przeczytał , dopóki A nie zwolni ich. Jednak A może wstawić nowe wiersze, które kwalifikują warunek gdzie (i dlatego następnym razem, gdy A wykona wybór, otrzyma inny wynik z większą liczbą wierszy - odczyt fantomowy).
BornToCode
9

Jak mówi brb tea, zależy to od implementacji bazy danych i używanego przez nią algorytmu: MVCC lub Two Phase Locking.

CUBRID (open source RDBMS) wyjaśnia ideę tych dwóch algorytmów:

  • Blokowanie dwufazowe (2PL)

Pierwsza z nich to gdy transakcja T2 próbuje zmienić rekord A, wie, że transakcja T1 już zmieniła rekord A i czeka, aż transakcja T1 zostanie zakończona, ponieważ transakcja T2 nie może wiedzieć, czy transakcja T1 zostanie zatwierdzona, czy rolowana plecy. Ta metoda nazywa się blokowaniem dwufazowym (2PL).

  • Kontrola współbieżności wielu wersji (MVCC)

Drugim jest umożliwienie każdej z nich, transakcjom T1 i T2, własnej zmienionej wersji. Nawet jeśli transakcja T1 zmieniła rekord A z 1 na 2, transakcja T1 pozostawia pierwotną wartość 1 taką jaka jest i zapisuje, że wersja transakcji T1 rekordu A to 2. Następnie następująca transakcja T2 zmienia rekord A od 1 do 3, a nie od 2 do 4, i pisze, że wersja transakcji T2 rekordu A to 3.

Kiedy transakcja T1 jest wycofywana, nie ma znaczenia, czy 2, wersja transakcji T1, nie zostanie zastosowana do rekordu A. Następnie, jeśli transakcja T2 zostanie zatwierdzona, do rekordu A zostanie zastosowana 3, wersja transakcji T2. Jeżeli transakcja T1 została zatwierdzona przed transakcją T2, rekord A zmienia się na 2, a następnie na 3 w momencie dokonywania transakcji T2. Ostateczny status bazy danych jest identyczny ze statusem wykonywania każdej transakcji niezależnie, bez wpływu na inne transakcje. Dlatego spełnia właściwość ACID. Ta metoda nosi nazwę kontroli współbieżności wielu wersji (MVCC).

MVCC umożliwia równoczesne modyfikacje kosztem zwiększonego narzutu w pamięci (ponieważ musi utrzymywać różne wersje tych samych danych) i obliczeń (na poziomie REPETEABLE_READ nie można stracić aktualizacji, więc musi sprawdzić wersje danych, np. Hiberate robi z Optimistick Locking ).

W 2PL poziomy izolacji transakcji kontrolują :

  • Czy blokady są przyjmowane podczas odczytu danych i jakiego rodzaju blokady są wymagane.

  • Jak długo utrzymywane są blokady odczytu.

  • Czy operacja odczytu odwołująca się do wierszy zmodyfikowanych przez inną transakcję:

    • Zablokuj, aż wyłączna blokada w rzędzie zostanie zwolniona.

    • Pobierz zatwierdzoną wersję wiersza, która istniała w momencie rozpoczęcia instrukcji lub transakcji.

    • Przeczytaj niezatwierdzoną modyfikację danych.

Wybranie poziomu izolacji transakcji nie wpływa na blokady, które są uzyskiwane w celu ochrony modyfikacji danych. Transakcja zawsze uzyskuje blokadę na wyłączność dla wszystkich modyfikowanych danych i blokuje tę blokadę do zakończenia transakcji, niezależnie od poziomu izolacji ustawionego dla tej transakcji. W przypadku operacji odczytu poziomy izolacji transakcji określają przede wszystkim poziom ochrony przed skutkami modyfikacji wprowadzonych przez inne transakcje.

Niższy poziom izolacji zwiększa zdolność wielu użytkowników do uzyskiwania dostępu do danych w tym samym czasie, ale zwiększa liczbę efektów współbieżności , takich jak brudne odczyty lub utracone aktualizacje, które mogą napotkać użytkownicy.

Konkretne przykłady relacji między blokadami i poziomami izolacji w SQL Server (użyj 2PL z wyjątkiem READ_COMMITED z READ_COMMITTED_SNAPSHOT = ON)

  • READ_UNCOMMITED: nie wystawiaj wspólnych blokad, aby uniemożliwić innym transakcjom modyfikację danych odczytanych przez bieżącą transakcję. Transakcje READ UNCOMMITTED również nie są blokowane przez blokady na wyłączność, które uniemożliwiłyby bieżącej transakcji odczytanie wierszy, które zostały zmodyfikowane, ale nie zostały zatwierdzone przez inne transakcje. […]

  • READ_COMMITED:

    • Jeśli READ_COMMITTED_SNAPSHOT jest ustawiona na OFF (wartość domyślna): używa wspólnych blokad, aby uniemożliwić innym transakcjom modyfikowanie wierszy, podczas gdy bieżąca transakcja wykonuje operację odczytu. Współdzielone blokady blokują również możliwość odczytu wierszy zmodyfikowanych przez inne transakcje w wyciągu do czasu zakończenia innej transakcji. [...] Blokady wierszy są zwalniane przed przetworzeniem następnego wiersza. […]
    • Jeśli READ_COMMITTED_SNAPSHOT jest ustawiona na ON, Aparat baz danych używa wersjonowania wierszy, aby przedstawić każdą instrukcję z transakcyjnie spójną migawką danych, jaka istniała na początku instrukcji. Blokady nie są używane do ochrony danych przed aktualizacjami przez inne transakcje.
  • REPETEABLE_READ: Blokady współdzielone są nakładane na wszystkie dane odczytane przez każdą instrukcję w transakcji i są utrzymywane do zakończenia transakcji.

  • SERIALIZOWALNY: Blokady zakresu są umieszczane w zakresie wartości kluczy, które pasują do warunków wyszukiwania każdej instrukcji wykonanej w transakcji. […] Blokady zakresu są utrzymywane do zakończenia transakcji.

gabrielgiussi
źródło
5

Blokady są zawsze pobierane na poziomie DB: -

Oficjalny dokument Oracle: - Aby uniknąć konfliktów podczas transakcji, DBMS używa blokad, mechanizmów blokowania dostępu innych osób do danych, do których ma dostęp transakcja. (Należy zauważyć, że w trybie automatycznego zatwierdzania, w którym każda instrukcja jest transakcją, blokady są utrzymywane tylko dla jednej instrukcji.) Po ustawieniu blokady pozostaje ona w mocy do momentu zatwierdzenia lub wycofania transakcji. Na przykład DBMS może zablokować wiersz tabeli do czasu zatwierdzenia aktualizacji. Efektem tej blokady byłoby zapobieżenie odczytaniu przez użytkownika brudnego odczytu, to znaczy odczytaniu wartości, zanim zostanie ona utrwalona. (Dostęp do zaktualizowanej wartości, która nie została zatwierdzona, jest uważany za brudny odczyt, ponieważ istnieje możliwość przywrócenia tej wartości do jej poprzedniej wartości. Jeśli odczytasz wartość, która jest później wycofywana, odczytasz nieprawidłową wartość. )

Sposób ustawiania blokad jest określany przez tak zwany poziom izolacji transakcji, który może wahać się od braku obsługi transakcji do obsługi transakcji, które wymuszają bardzo rygorystyczne zasady dostępu.

Jednym z przykładów poziomu izolacji transakcji jest TRANSACTION_READ_COMMITTED, który umożliwi dostęp do wartości dopiero po jej zatwierdzeniu. Innymi słowy, jeśli poziom izolacji transakcji jest ustawiony na TRANSACTION_READ_COMMITTED, DBMS nie zezwala na występowanie brudnych odczytów. Interfejs Connection zawiera pięć wartości, które reprezentują poziomy izolacji transakcji, których można używać w JDBC.

Goyal Vicky
źródło