Ответ
При одновременном доступе нескольких транзакций к одним и тем же данным могут возникать следующие аномалии:
-
Потерянное обновление (Lost Update) Происходит, когда две транзакции читают одну и ту же запись, обе изменяют её, а затем сохраняют. Изменение, сделанное первой транзакцией, будет перезаписано второй. Пример: Два пользователя одновременно редактируют статью. Первый сохраняет изменения, а через секунду второй сохраняет свои, затирая работу первого.
-
«Грязное» чтение (Dirty Read) Одна транзакция читает данные, которые были изменены другой транзакцией, но ещё не зафиксированы (не выполнен
COMMIT). Если вторая транзакция в итоге будет отменена (ROLLBACK), первая будет работать с неактуальными, "грязными" данными. -
Неповторяемое чтение (Non-Repeatable Read) В рамках одной транзакции происходит повторное чтение одной и той же строки, но результаты оказываются разными. Это случается, если между чтениями другая транзакция успела изменить или удалить эту строку и зафиксировать изменения.
-
Фантомное чтение (Phantom Read) Похоже на неповторяемое чтение, но связано с появлением новых записей. Когда одна транзакция повторно выполняет запрос с одним и тем же условием
WHERE, она получает разное количество строк, потому что другая транзакция успела добавить новые строки, удовлетворяющие этому условию.
Способы борьбы:
- Уровни изоляции транзакций: Основной механизм в SQL. Уровни (
READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ,SERIALIZABLE) определяют, какие аномалии допустимы, а какие нет, обеспечивая компромисс между согласованностью данных и производительностью. - Блокировки:
- Пессимистические: Явная блокировка записей на время их чтения и изменения (например,
SELECT ... FOR UPDATEв PostgreSQL), чтобы другие транзакции не могли их изменять. - Оптимистические: Проверка перед записью, не изменились ли данные с момента их чтения (например, с помощью поля
version). Если изменились — транзакция откатывается.
- Пессимистические: Явная блокировка записей на время их чтения и изменения (например,
Ответ 18+ 🔞
Давай разберем эту хрень, которая в базах данных творится, когда все лезут в одну кучу. Представь, что данные — это последняя булка в столовой, а транзакции — это мы с тобой голодные. Вот что может пойти не так, ёпта:
-
Потерянное обновление (Lost Update) Вообще пиздец, классика. Два чела одновременно хватают один файл, оба его меняют и сохраняют. Кто последний нажал «Сохранить», тот и красавчик, а работа первого — накрылась медным тазом, в топку. Пример: Сидят два редактора в одной статье. Вася дописал гениальный абзац, сохранил. А Петя, который на секунду позже начал, тупо затер всё Васино своим кривым текстом и тоже сохранил. Вася в ауте.
-
«Грязное» чтение (Dirty Read) Тут один чувак уже начал менять данные, но ещё не сказал «ВСЁ, ГОТОВО!» (то есть
COMMITне сделал). А второй, нетерпеливый, уже суёт свой нос и читает эти сырые, промежуточные данные. А если первый потом передумает и откатит всё нахуй (ROLLBACK), то второй останется с полной хуйней в руках, с которой уже поработал. Э сабака, сука! -
Неповторяемое чтение (Non-Repeatable Read) Ситуация для параноиков. Ты в рамках своей операции прочитал какую-то строчку. Отвлёкся на секунду, а когда через мгновение перечитал её — а там уже другие цифры! Оказалось, пока ты моргал, другая транзакция проскочила и эти данные поменяла. Волнение ебать, где правда?
-
Фантомное чтение (Phantom Read) Это ещё хитрее, блядь. Ты два раза подряд делаешь один и тот же запрос, например «дай всех, у кого зарплата больше ста». В первый раз тебе вернулось 10 записей. Ты думаешь: «О, окей». А делаешь второй раз — а их уже 11! Откуда? Да пока ты думал, какой-то хитрожопый менеджер успел нового сотрудника на зарплату в 150к впихнуть. Вот эти новые, внезапно появившиеся строки — они и есть фантомы, ёперный театр.
И как со всем этим бороться, спросишь ты?
- Уровни изоляции транзакций: Это главный костыль, который придумали умные дяди. Есть такие режимы —
READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ,SERIALIZABLE. Чем строже уровень, тем меньше аномалий он допускает, но зато всё работает медленнее, как говно в проруби. Выбирай, что тебе дороже: скорость или чтобы голова не болела. - Блокировки:
- Пессимистические: Работают по принципу «доверия ебать ноль». Как только ты начинаешь работать с записью, ты её сразу хватаешь и вешаешь замок (
SELECT ... FOR UPDATE). Никто другой не подступится, пока ты не отпустишь. Надёжно, но если все будут так делать, можно в дедлоке все повиснуть. - Оптимистические: Тут ты всем веришь, как последний лох. Работаешь с копией данных, а когда пришло время сохранять, проверяешь: «А не изменил ли кто эту запись, пока я тут умничал?». Если нет — ок, пишешь. Если да — охуеваешь и начинаешь всё заново. Способ для терпеливых.
- Пессимистические: Работают по принципу «доверия ебать ноль». Как только ты начинаешь работать с записью, ты её сразу хватаешь и вешаешь замок (