Ответ
При одновременном выполнении транзакций без должной изоляции могут возникать следующие аномалии:
Потерянное обновление (Lost Update)
- Проблема: Одна транзакция перезаписывает изменения другой.
- Сценарий:
- Транзакция 1 читает баланс счёта (1000).
- Транзакция 2 читает тот же баланс (1000).
- Транзакция 1 добавляет 100 и записывает баланс (1100).
- Транзакция 2 добавляет 200 к своему прочитанному значению и записывает баланс (1200).
- Результат: Обновление от Транзакции 1 потеряно. Итоговый баланс 1200, а не 1300.
Грязное чтение (Dirty Read)
- Проблема: Транзакция читает данные, которые были изменены другой транзакцией, но ещё не зафиксированы (не
COMMIT
). Если вторая транзакция откатится (ROLLBACK
), первая будет работать с недействительными данными. - Предотвращается уровнем:
Read Committed
и выше.
- Проблема: Транзакция читает данные, которые были изменены другой транзакцией, но ещё не зафиксированы (не
Неповторяемое чтение (Non-Repeatable Read)
- Проблема: Повторное чтение одной и той же строки в рамках одной транзакции возвращает разные значения. Это происходит, если другая транзакция успевает изменить и зафиксировать эти данные между чтениями.
- Предотвращается уровнем:
Repeatable Read
и выше.
Фантомное чтение (Phantom Read)
- Проблема: Повторное выполнение запроса с условием выборки (например,
SELECT ... WHERE age > 30
) в рамках одной транзакции возвращает разное количество строк. Это происходит, если другая транзакция добавляет или удаляет строки, удовлетворяющие этому условию. - Предотвращается уровнем:
Serializable
.
- Проблема: Повторное выполнение запроса с условием выборки (например,
Правильный выбор уровня изоляции транзакций является основным способом предотвращения этих аномалий на уровне СУБД.