Dostępny interfejs dostępu do baz danych w Javie (JDBC) udostępnia kilka różnych poziomów izolacji poszczególnych transakcji. Pozwala na określenie, jak bardzo poszczególne transakcje mają być oddzielone od siebie. Niezależnie od poziomu izolacji transakcji, operacje takie jak wstawianie (INSERT
), usuwanie (DELETE
) oraz modyfikowanie (UPDATE
) rekordów zachowują się zawsze tak samo, jedynie zachowanie operacji pobierającej (SELECT
) dane z tabeli może być rożne.
Poziom transakcji jest ustawiany w ramach pojedynczego połączenia z bazą danych. Można go ustawia się go przy użyciu metody Connection.setTransactionIsolation()
. Im wyższy poziom izolacji transakcji tym generalnie mniejsza wydajność operacji na bazie danych oraz większe prawdopodobieństwo wystąpienia blokad w dostępie do bazy danych.
Anomalie występujące w transakcjach
Poniżej znajduje się zestawienie anomalii, jakie mogą wystąpić w transakcjach:
Nazwa anomalii | Przykład działania anomalii |
---|---|
Dirty Reads
Mamy z nią do czynienia wtedy, gdy następuje w danej transakcji A odczyt zmodyfikowanych w transakcji B danych, a transakcja ta (B) nie została jeszcze zatwierdzona. |
Transakcja A rozpoczyna się, i wywołuje:
SELECT * FROM zamowienia Transakcja B w tym samym czasie wykonuje: UPDATE zamowienie SET wartosc_zamowienia=100 WHERE nr_zamowienia=123 Istnieje możliwość, że w transakcji A zostanie odczytana nowa wartość pola |
Non-Repeatable Reads
Ze zdarzeniem takim mamy do czynienia wtedy, gdy zapytania A wykonane w różnych momentach jednej transakcji może zwrócić inne wyniki (to samo zapytanie nie daje tego samego rezultatu). Zdarzyć się tak może, gdy w trakcie działania transakcji dane zostaną zmodyfikowane przez inną operacje na bazie danych. |
Transakcja A rozpoczyna się, i wywołuje:
SELECT * FROM zamowienia WHERE nr_zamowienia=123 Transakcja B w tym samym czasie wykonuje: UPDATE zamowienie SET wartosc_zamowienia=100 WHERE nr_zamowienia=123; COMMIT; Wykonanie ponowne zapytania w transakcji A spowoduje, że zostanie tym razem zwrócony zmodyfikowany rekord. |
Phantom Reads
Z taką sytuacją mamy do czynienia wtedy, gdy transakcja A odczytuje dane z bazy danych, w trakcie jej trwanie transakcja B umieści w bazie danych rekord, który spełnia warunki zapytania z transakcji A. Jeżeli teraz w transakcji ponownie zostanie wykonane zapytanie, nowy rekord także zostanie zwrócony, co powoduje niezgodność wyniku działania dwóch zapytań w ramach tej samej transakcji. |
Transakcja A odczytuje dane:
SELECT * FROM zamowienia WHERE nr_zamowienia > 123 Transakcja B wstawia nowy wiersz do tabeli: INSERT INTO zamowienia (nr_zamowienia, nazwa) VALUES ('140', 'Babol złapany'); COMMIT; Jeżeli teraz w transakcji A ponownie wykonamy zapytanie, to nowy rekord także zostanie pobrany. |
Poziomy transakcji
Rozróżniane są następujące poziomy transakcji:
- TRANSACTION_READ_UNCOMMITTED
Brak izolacji. Wszelkie zmiany, także te które nie są zatwierdzone jeszcze, są widoczne dla wszystkich zapytań w bazie danych.
- TRANSACTION_READ_COMMITTED
Minimalna izolacja, transakcje widzą tylko takie dane, które już są zatwierdzone i zapisane w bazie danych.
- TRANSACTION_REPEATABLE_READ
Poziom ten zapewnia powtarzalność odczytu danych. Jeżeli jakiś rekord zostanie odczytany, to nawet jego zatwierdzona modyfikacja w innej transakcji nie zmieni jego wartości przy ponownym odczycie.
- TRANSACTION_SERIALIZABLE
Najwyższy poziom transakcji, zwany szeregowym. Zapewnia on najlepszą izolację poszczególnych transakcji, które nie widzą swoich wzajemnych działań i nie wpływają na siebie. W momencie rozpoczęcia transakcji, stan bazy danych jest „zamrażany” i tylko na takim stanie transakcja może działać.
Nazwa transakcji | Blokada tabeli | Blokada wiersza | Wydajność |
---|---|---|---|
TRANSACTION_READ_UNCOMMITTED | Możliwe: dirty reads, non-repeatable reads, phantom reads | Możliwe: dirty reads, non-repeatable reads, phantom reads | najszybsza |
TRANSACTION_READ_COMMITTED | Możliwe: non-repeatable reads i phantom reads | Możliwe: non-repeatable reads i phantom reads | szybka |
TRANSACTION_REPEATABLE_READ | Ponieważ blokowana jest cała tabela, to phantom reads nie są możliwe | Możliwe są phantom reads | średnia |
TRANSACTION_SERIALIZABLE | Brak anomalii | Brak anomalii | wolna |