Какие существуют аномалии параллельных транзакций в базах данных?

Ответ

При одновременном доступе нескольких транзакций к одним и тем же данным могут возникать следующие аномалии:


  1. Потерянное обновление (Lost Update)

    Происходит, когда две транзакции читают одну и ту же запись, обе изменяют её, а затем сохраняют. Изменение, сделанное первой транзакцией, будет перезаписано второй.

    Пример: Два пользователя одновременно редактируют статью. Первый сохраняет изменения, а через секунду второй сохраняет свои, затирая работу первого.



  2. «Грязное» чтение (Dirty Read)

    Одна транзакция читает данные, которые были изменены другой транзакцией, но ещё не зафиксированы (не выполнен COMMIT). Если вторая транзакция в итоге будет отменена (ROLLBACK), первая будет работать с неактуальными, "грязными" данными.



  3. Неповторяемое чтение (Non-Repeatable Read)

    В рамках одной транзакции происходит повторное чтение одной и той же строки, но результаты оказываются разными. Это случается, если между чтениями другая транзакция успела изменить или удалить эту строку и зафиксировать изменения.



  4. Фантомное чтение (Phantom Read)

    Похоже на неповторяемое чтение, но связано с появлением новых записей. Когда одна транзакция повторно выполняет запрос с одним и тем же условием WHERE, она получает разное количество строк, потому что другая транзакция успела добавить новые строки, удовлетворяющие этому условию.


Способы борьбы:

  • Уровни изоляции транзакций: Основной механизм в SQL. Уровни (READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE) определяют, какие аномалии допустимы, а какие нет, обеспечивая компромисс между согласованностью данных и производительностью.
  • Блокировки:
    • Пессимистические: Явная блокировка записей на время их чтения и изменения (например, SELECT ... FOR UPDATE в PostgreSQL), чтобы другие транзакции не могли их изменять.
    • Оптимистические: Проверка перед записью, не изменились ли данные с момента их чтения (например, с помощью поля version). Если изменились — транзакция откатывается.