Izolacje transakcji.

W poprzednim artykule wprowadziłam Cię w pojęcie transakcji w bazie danych. Dzisiejszy artykuł izolacje transakcji czy też blokowanie transakcji jest jego kontynuacją.  Jeśli więc nie czytałeś/łaś poprzedniego artykułu „Transakcja w bazie danych” serdecznie Cię tam zapraszam. Ułatwi  to zrozumienie jaką rolę pełnią izolacje transakcji 🙂

1. 4 Izolacje transakcji – poziomy

Występują 4 poziomy izolacji transakcji:

  1. Read uncommitted
  2. Read commited
  3. Repeatable read
  4. Serializable

Tabela poniżej przedstawia podział izolacji transakcji oraz problemy jakie im towarzyszą.

Sql: poziomy izloacji transakcji i dozwolne operacje
poziomy izolacji transakji i problemy dla każdego poziomu.

2. Izolacje transakcji w bazie danych Oracle.

Na przykładzie bazy danych Oracle przestawię poziomy izolacji:

  1. Read Commited i
  2. Serializable.

Wynika to z faktu iż Oracle wpiera tyle te dwa rodzaje izolacji. Poza „isolation level” występuje tutaj również możliwość ustawienia transakcji na :

  1. Read Only lub
  2. Read Write.

Jaka jest różnica? Te drugie zawierają się w pierwszych. Np. Read Only jest podzbiorem (subset) dla Serializable. Natomiast Seralizable jest nadzbiorem (superset) dla Read Only.

ustawienia transakcji w Oracle - możliwe opcje
ustawienia transakcji w Oracle – możliwe opcje.

3. Izolacje transakcji: Read Commited.

Możemy ją ustawić komendą alter session set isolation_level  = read committed. Nie trzeba jednak tego robić ponieważ ten poziom izolacji jest dla bazy danych Oracl’a domyślnym. 

Poziom ten dopuszcza Phantom Read oraz Non Reapatable Read. Przetestujemy więc read commited na bazie Oracle. W moim przykładzie wszystko dzieje się na tabeli employees.

Jak możemy zobaczyć poniżej w dwóch sesjach po wybraniu operacji select widzimy dokładnie to samo 4-trech praconików.

Sesja nr 1: izolacja transakcji Read commited, transacja select all from employees
Sesja nr 1: izolacja transakcji Read commited, transacja select all from employees
Sesja nr 2: izolacja transakcji Read commited, transacja select all from employees
Sesja nr 2: izolacja transakcji Read commited, transacja select all from employees
 
 

3.1 Read Commited – Phantom Read.

Spróbujemy więc zrobić modyfikacje w sesji nr.1 i dodajmy nowego pracownika. Następnie przed zatwierdzeniem i po zatwierdzeniu transakcji sprawdzimy czy operacja dodania jest już widoczna w sesji nr. 2. Dodałam również kolumnę z czasem, dzięki której jeszcze lepiej będziemy mogli zobaczyć w jakiej kolejności wszystko się dzieje. Przejdźmy więc do sesji nr 1. Został dodany nowy pracownik co jest już widoczne.
Sesja nr.1: dodanie nowego rekodu i sprawdzenie przed i po skomitowanu czy sesja nr.1 odczytuje transakcje.
Sesja nr.1: dodanie nowego rekodu i sprawdzenie przed i po skomitowaniu czy sesja nr.1 odczytuje transakcje.

Pójdźmy teraz do drugiej sesji w której widźmy że niezatwierdzona transakcja  z sesji nr. 1 nie jest widoczna. Użytkownik w sesji nr. 2 nic nie wie o nowym pracowniku. Porównajmy czasy transakcji: widzimy że dodanie pracownika i zatwierdzenie transakcji nastąpiło o 23:09:30. Użytkownik z sesji nr.2 widzi zmiany z sesji nr.1  z godz.: 23:08:33 po wykonaniu operacji commit w sesji nr.1. W naszym przykładzie to 23:09:49.

session2_insert_widoczny
Sesja nr.2:sprawdzenie kiedy transakacja z sesji nr.1 jest gotowa do odczytu w sesji nr.2

Wiersz który został dodany jest naszym „Phantom Read”. Czyli takim który pojawia się i znika podczas dwóch identycznych zapytaniach. Problem dotyczy również operacji delete np delete * from where id = 7;

 

3.2 Read Commited – Non Reapatable Read

Spójrzmy jeszcze raz na tabele Employees. Tym razem na wybranym pracowniku dokonam modyfikacji wynagrodzenia. Podobnie jak poprzednio zaczęłam od sprawdzania zawartości tabeli czy  są one identyczne w obu sesjach. Następnie dokonałam drobnej modyfikacji i sprawdziłam w którym momencie owa zmiana jest widoczna w sesji nr.2. Oto rezultaty: początkowo dane są identyczne:

zawartość tabeli employees
Sesja nr.1 zawartość tabeli employees
Identyczna zawartość tabeli employees
Sesja nr 2. Identyczna zawartość tabeli employees.

Jednak po dokonaniu operacji „update” aktualizacje widzimy tylko w sesji wykonania. Spójrzmy na godzinę wykonania 22:29:45 oraz na zmianę w kolumnie „salary”.

Sesja nr. 1 sprawdzenie modyfikacji employee na nr id = 7
Sesja nr. 1 sprawdzenie modyfikacji employee na nr id = 7.

Następnie porównajmy to z zawartością tabeli z drugiej sesji. Pomimo tego iż godzina jest nieco późniejsza aktualizacja nie jest widoczna. Dzieje się tak dlatego że w sesji nr1 transakcja nie została zakończona np. poprzez commit.

Sesja nr.2 sprawdzenie czy update z sesji nr2 jest widoczny.
Sesja nr.2 sprawdzenie czy update z sesji nr2 jest widoczny.

Powróćmy teraz ponownie do sesji nr. 1. Jednak tym razem aby zakończyć operację „update” z godziną 22:30:57

Sesja nr 1. Zakończenie transakcji i sprawdzenie czasów.
Sesja nr 1. Zakończenie transakcji i sprawdzenie czasów.

I ponownie powróćmy do sesji nr.2 aby sprawdzić zawartośc tabeli. Jak widać poniżej dane są identyczne z danymi w sesji nr.1.

Sesja nr2. Ponowne sprawdzenie widoczności operacji update po zatwierdzeni transakcji w sesji nr.1
Sesja nr2. Ponowne sprawdzenie widoczności operacji update po zatwierdzeni transakcji w sesji nr.1

Tak więc wiersz który był modyfikowany jest naszym „Non Reapatable Read”. Pojawia się on gdy dany rekord jest wyszukiwany więcej niż raz i za każdym razem ma inną wartość, ponieważ w miedzy czasie doszło do modyfikacji.

 
 

4. Podsumowanie

W dzisiejszym artykule nauczyliśmy się co to takiego Phantom read i Non Reapatable Read oraz w której izolacji transakcji one występują. A jakie tym masz doświadczenia z tego typu operacjami? Koniecznie podziel się w komentarzu 🙂

Leave a Comment

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *