2.1 Przeczytaj niezobowiązujące
„Poziom izolacji transakcji” odnosi się do stopnia ochrony zapewnianej przez wewnętrzne mechanizmy SZBD (tj. nie wymagającego specjalnego programowania) przed wszystkimi lub niektórymi z powyższych rodzajów niespójności danych, które występują podczas równoległego wykonywania transakcji. Standard SQL-92 definiuje skalę czterech poziomów izolacji:
- Przeczytaj bez zobowiązań
- Przeczytaj zobowiązana
- Powtarzalny odczyt
- Możliwość serializacji
Pierwszy z nich jest najsłabszy, ostatni najsilniejszy, każdy kolejny zawiera w sobie wszystkie poprzednie.
Najniższy (pierwszy) poziom izolacji. Jeśli kilka równoległych transakcji spróbuje zmodyfikować ten sam wiersz tabeli, ostatni wiersz będzie miał wartość określoną przez cały zestaw pomyślnie zakończonych transakcji. W takim przypadku możliwy jest odczyt nie tylko danych niespójnych logicznie, ale także danych, których zmian jeszcze nie zarejestrowano.
Typowym sposobem implementacji tego poziomu izolacji jest zablokowanie danych podczas wykonywania polecenia zmiany, co gwarantuje, że polecenia modyfikacji w tych samych wierszach wykonywane równolegle są faktycznie wykonywane sekwencyjnie i żadna ze zmian nie zostanie utracona. Transakcje tylko do odczytu nigdy nie są blokowane na tym poziomie izolacji.
2.2 Przeczytaj popełnione
Większość przemysłowych systemów DBMS, w szczególności Microsoft SQL Server, PostgreSQL i Oracle, domyślnie używa tego poziomu. Na tym poziomie zapewniona jest ochrona przed „brudnym” odczytem, jednak w trakcie operacji jednej transakcji druga może zostać pomyślnie zakończona, a dokonane przez nią zmiany zostaną utrwalone. W rezultacie pierwsza transakcja będzie działać z innym zestawem danych.
Implementacja pełnego odczytu może opierać się na jednym z dwóch podejść: blokowaniu lub wersjonowaniu.
Blokowanie czytelnych i modyfikowalnych danych.
Polega ona na tym, że transakcja zapisu blokuje dane zmienne dla transakcji odczytu działających na poziomie zatwierdzenia odczytu lub wyższym do czasu jego zakończenia, zapobiegając w ten sposób „brudnemu” odczytowi, a dane zablokowane przez transakcję odczytu są zwalniane natychmiast po zakończeniu operacji SELECT
(w związku z tym na danym poziomie izolacji może wystąpić sytuacja „niepowtarzalnego odczytu”).
Zapisywanie wielu wersji wierszy, które zmieniają się równolegle.
Za każdym razem, gdy wiersz jest zmieniany, DBMS tworzy nową wersję tego wiersza, z którą transakcja, która zmieniła dane, nadal działa, podczas gdy każda inna transakcja „odczytu” zwraca ostatnią zatwierdzoną wersję. Zaletą tego podejścia jest to, że jest szybsze, ponieważ zapobiega blokowaniu. Wymaga jednak, w porównaniu z pierwszym, znacznie większego zużycia pamięci RAM, która jest przeznaczana na przechowywanie wersji wierszowych.
Ponadto, gdy wiele transakcji zmienia dane równolegle, może to spowodować sytuację, w której kilka jednoczesnych transakcji dokonuje niespójnych zmian w tych samych danych (ponieważ nie ma blokad, nic temu nie zapobiegnie). Wtedy transakcja, która zatwierdzi jako pierwsza, zapisze swoje zmiany w głównej bazie danych, a pozostałe transakcje równoległe będą niemożliwe do zatwierdzenia (ponieważ doprowadzi to do utraty aktualizacji pierwszej transakcji). Jedyne, co DBMS może zrobić w takiej sytuacji, to wycofać resztę transakcji i wystawić komunikat o błędzie „Rekord został już zmieniony”.
Deweloperzy DBMS wybierają konkretną metodę implementacji, aw niektórych przypadkach można ją dostosować. Tak więc domyślnie MS SQL używa blokad, ale (w wersji 2005 i wyższych) podczas ustawiania READ_COMMITTED_SNAPSHOT
parametru bazy danych przełącza się na strategię wersjonowania, Oracle początkowo działa tylko według schematu wersjonowania. W Informix można zapobiegać konfliktom między transakcjami odczytu i zapisu, ustawiając opcję konfiguracji USELASTCOMMITTED
(od wersji 11.1), która powoduje, że transakcja odczytu otrzymuje najnowsze zatwierdzone dane.
2.3 Odczyt powtarzalny
Poziom, na którym transakcja odczytu „nie widzi” zmienia dane, które wcześniej odczytała. Jednocześnie żadna inna transakcja nie może zmienić danych odczytanych przez bieżącą transakcję, aż do jej zakończenia.
Blokady w trybie współdzielonym są nakładane na wszystkie dane odczytywane przez dowolną instrukcję w transakcji i są utrzymywane do momentu zakończenia transakcji. Zapobiega to modyfikowaniu przez inne transakcje wierszy, które zostały odczytane przez oczekującą transakcję. Jednak inne transakcje mogą wstawiać znaki nowej linii, które odpowiadają warunkom wyszukiwania instrukcji zawartych w bieżącej transakcji. Gdy instrukcja zostanie ponownie uruchomiona przez bieżącą transakcję, zostaną pobrane nowe wiersze, co spowoduje odczyt fantomowy.
Biorąc pod uwagę, że wspólne blokady są utrzymywane do końca transakcji, a nie zwalniane na końcu każdej instrukcji, stopień współbieżności jest niższy niż poziom izolacji READ COMMITTED
. Dlatego ogólnie nie zaleca się niepotrzebnego korzystania z tego i wyższych poziomów transakcji.
2.4 Możliwość serializacji
Najwyższy poziom izolacji; transakcje są od siebie całkowicie odizolowane, każda jest wykonywana tak, jakby nie było transakcji równoległych. Tylko na tym poziomie transakcje współbieżne nie podlegają efektowi „odczytu fantomowego”.
2.5 Wsparcie izolacji transakcji w prawdziwym DBMS
Transakcyjne DBMS nie zawsze obsługują wszystkie cztery poziomy, a także mogą wprowadzać dodatkowe. Istnieją również różne niuanse w zapewnianiu izolacji.
Oracle w zasadzie nie obsługuje więc poziomu zerowego, gdyż jego implementacja transakcji wyklucza „brudne odczyty”, a formalnie nie pozwala na ustawienie poziomu odczytu Repeatable, czyli obsługuje tylko (domyślnie) Read committed
i Serializable
. Jednocześnie na poziomie poszczególnych poleceń faktycznie gwarantuje powtarzalność odczytu (jeżeli polecenie SELECT
w pierwszej transakcji wybiera zestaw wierszy z bazy danych, a w tym czasie równoległa druga transakcja zmienia niektóre z tych wierszy, to zestaw wyników otrzymany przez pierwszą transakcję będzie zawierał niezmienione wiersze, tak jakby drugiej transakcji nie było). Oracle obsługuje również tzw. READ-ONLY
transakcje, które odpowiadają Serializable
, ale nie mogą same zmieniać danych.
A Microsoft SQL Server obsługuje wszystkie cztery standardowe poziomy izolacji transakcji, a dodatkowo poziom SNAPSHOT, na którym transakcja widzi stan danych, które zostały zatwierdzone przed jej uruchomieniem, a także wprowadzone przez siebie zmiany, czyli zachowuje się tak, jakby podczas uruchamiania otrzymał migawkę danych bazy danych i współpracuje z nią. Różnica w stosunku do Serialized polega na tym, że nie są używane żadne blokady, ale w rezultacie zatwierdzenie zmian może nie być możliwe, jeśli jednoczesna transakcja zmieniła wcześniej te same dane; w takim przypadku druga transakcja przy próbie wykonania COMMIT
zgłosi komunikat o błędzie i zostanie anulowana.
GO TO FULL VERSION