Стандарт SQL визначає чотири рівні - від найслабшого до найсуворішого. Кожен забороняє більше аномалій:
| Рівень | Брудне читання | Неповторюване читання | Фантоми |
|---|---|---|---|
| Read Uncommitted | можливе | можливе | можливі |
| Read Committed | ні | можливе | можливі |
| Repeatable Read | ні | ні | можливі (за стандартом) |
| Serializable | ні | ні | ні |
- Брудне читання - бачимо незакомічені зміни іншої транзакції.
- Неповторюване читання - той самий рядок, прочитаний двічі, змінився між читаннями.
- Фантом - повторний запит з тією ж умовою повертає нові рядки.
На практиці:
- PostgreSQL за замовчуванням Read Committed. Read Uncommitted поводиться як Read Committed. Його Repeatable Read фантомів не допускає (снапшот на всю транзакцію), а Serializable реалізований через SSI.
- MySQL InnoDB за замовчуванням Repeatable Read. Звичайні
SELECTчитають снапшот, але блокувальні читання (FOR UPDATE) іUPDATEбачать найсвіжіші дані.
Що це означає для коду: класична гонка «прочитав баланс → перевірив → записав» не захищена на Read Committed. Рішення - атомарний UPDATE ... SET balance = balance - 100 WHERE balance >= 100, блокування FOR UPDATE або Serializable.
На Repeatable Read і Serializable база може відхилити транзакцію з помилкою серіалізації. Застосунок мусить бути готовий повторити таку транзакцію - це частина контракту, а не збій.