Poziomy izolacji (isolation levels) to ustawienie bazy danych, które decyduje, jak bardzo równolegle działające transakcje są od siebie odgrodzone — czyli ile nawzajem widzą ze swoich jeszcze niezatwierdzonych lub świeżo zatwierdzonych zmian. Standard ANSI/ISO SQL definiuje cztery poziomy: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ i SERIALIZABLE — uszeregowane od najluźniejszego do najściślejszego. Im wyżej, tym mniej dziwnych anomalii, ale też tym więcej blokad i niższa współbieżność. To klasyczny handel: spójność za wydajność.
Jak to działa
Poziom izolacji określa, na które z trzech klasycznych anomalii odczytu jesteś narażony. Dirty read to odczyt danych, które inna transakcja zapisała, ale jeszcze nie zatwierdziła (i może je wycofać). Non-repeatable read — czytasz ten sam wiersz dwa razy w jednej transakcji i dostajesz różne wartości, bo ktoś go w międzyczasie zmienił. Phantom read — ten sam SELECT ... WHERE zwraca raz 5, raz 6 wierszy, bo ktoś dorzucił nowy rekord pasujący do warunku.
Reguła jest prosta: READ UNCOMMITTED dopuszcza wszystkie trzy, READ COMMITTED blokuje dirty reads, REPEATABLE READ dokłada ochronę przed non-repeatable reads, a SERIALIZABLE teoretycznie eliminuje też phantomy — transakcje wykonują się tak, jakby leciały jedna po drugiej. Silniki realizują to różnie: przez blokady (locking) albo przez wersjonowanie wierszy (MVCC), gdzie czytelnicy dostają migawkę danych zamiast czekać na piszących.
Przykład z praktyki
W PostgreSQL ustawiasz poziom na starcie transakcji:
BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- zapytania ...; COMMIT;
Drobny haczyk: domyślny poziom w PostgreSQL i Oracle to READ COMMITTED, ale w MySQL z silnikiem InnoDB domyślnie dostajesz REPEATABLE READ. Jeśli przenosisz aplikację między bazami i nie sprawdzisz SHOW VARIABLES LIKE 'transaction_isolation';, możesz złapać subtelne różnice w zachowaniu raportów finansowych.
Na co uważać
Mit numer jeden: „ustawię SERIALIZABLE i będzie bezpiecznie”. Owszem, ale w PostgreSQL grozi to błędem could not serialize access i transakcja zostaje wycofana — Twój kod musi umieć ją powtórzyć, inaczej user zobaczy losowy crash. Mit numer dwa: nazwy poziomów znaczą wszędzie to samo. Nie znaczą — REPEATABLE READ w InnoDB dzięki MVCC tłumi też phantomy, czego standard nie wymaga. Zanim podniesiesz poziom „dla świętego spokoju”, zmierz wpływ na blokady i throughput.
Pojęcia powiązane
ACID, transakcja, MVCC, blokady (locking), dirty read, phantom read, deadlock, optimistic vs pessimistic concurrency control.