Грязное чтение
Dirty read возникает, когда транзакция читает изменение, которое другая транзакция еще не зафиксировала.
T1: BEGIN
T1: UPDATE orders SET total = 0 WHERE id = 42
T2: SELECT total FROM orders WHERE id = 42 -- увидела 0
T1: ROLLBACKТранзакция T2 использовала значение, которого в зафиксированном состоянии базы никогда не существовало.
Чем опасно
- отчет или решение строятся на откатившихся данных;
- наружу может уйти уведомление о несуществующем состоянии;
- зависимые вычисления уже нельзя «откатить» вместе с чужой транзакцией.
Уровень READ COMMITTED и выше по стандарту запрещает dirty read. Многие MVCC-СУБД фактически не допускают его даже на уровне с названием READ UNCOMMITTED, но это проверяют по документации своей СУБД.
Не путать
- non-repeatable read: читали только committed-значения, но они изменились между двумя запросами;
- dirty write: одна транзакция перезаписала незакоммиченное изменение другой;
- stale read: прочитали старую, но корректно зафиксированную версию, например с реплики.
Связано: Изоляция транзакций, Опасности использования read committed, Repeatable read.
Вопросы
Почему чтение называется грязным? Значение еще не стало частью зафиксированного состояния.
Защищает ли Read Committed? Да, от dirty read, но не от изменения данных между операторами.
Является ли чтение с отстающей реплики dirty read? Нет; это устаревшее committed-состояние.