Ответ
Это две аномалии согласованности, которые могут возникать при параллельном выполнении транзакций, в зависимости от уровня изоляции.
Неповторяющееся чтение (Non-repeatable Read)
- Суть: В рамках одной транзакции два одинаковых запроса
SELECTвозвращают разные данные для одних и тех же строк из-за того, что другая параллельная транзакция изменила и зафиксировала эти данные между первым и вторым чтением. - Пример:
- Транзакция A читает баланс счета (100$).
- Транзакция B изменяет баланс этого счета на 50$ и фиксирует изменения.
- Транзакция A снова читает баланс того же счета и получает 50$ (результат изменился).
Фантомное чтение (Phantom Read)
- Суть: В рамках одной транзакции два одинаковых запроса
SELECTвозвращают разное количество строк из-за того, что другая параллельная транзакция добавила или удалила строки, удовлетворяющие условию запроса, между первым и вторым чтением. - Пример:
- Транзакция A выполняет
SELECT * FROM users WHERE age > 18и получает 10 строк. - Транзакция B вставляет новую запись с
age=25и фиксирует изменения. - Транзакция A повторяет тот же
SELECTи получает 11 строк (появилась "фантомная" строка).
- Транзакция A выполняет
Как предотвращаются?
- Неповторяющееся чтение предотвращается на уровнях изоляции REPEATABLE READ и выше.
- Фантомное чтение в стандарте SQL предотвращается только на уровне SERIALIZABLE. Однако некоторые СУБД (например, MySQL InnoDB при
REPEATABLE READ) также предотвращают фантомы за счёт механизма многоверсионности (MVCC) и gap-блокировок.