Вопрос с собеседования · Базы данных

Что такое потерянное обновление и как его избежать?

JuniorТранзакции и изоляция
Ещё спрашивают так:
  • Зачем нужен SELECT FOR UPDATE?
  • Почему два одновременных запроса портят счётчик?
Коротко

Два запроса одновременно читают одно значение (остаток 10), каждый вычисляет новое (10 − 1 = 9) и записывает — в итоге 9 вместо 8: одно обновление потеряно. Защита: атомарное обновление в одном запросе (UPDATE ... SET stock = stock - 1 WHERE stock > 0), пессимистическая блокировка строки (SELECT ... FOR UPDATE внутри транзакции) или оптимистическая с версией (UPDATE ... WHERE version = ?).

  • Схема «прочитать в приложении — посчитать — записать» без защиты небезопасна
  • Атомарный UPDATE — самый простой и быстрый вариант
  • Уровень изоляции Read Committed по умолчанию от этого не защищает

А ещё Проверка: число затронутых строк — 0 значит, условие не выполнилось

Подробно

Плохо:

stock = db.fetch("SELECT stock FROM items WHERE id = 1")
db.execute("UPDATE items SET stock = %s WHERE id = 1", stock - 1)

Хорошо:

UPDATE items SET stock = stock - 1 WHERE id = 1 AND stock > 0;

Или в транзакции:

BEGIN;
SELECT stock FROM items WHERE id = 1 FOR UPDATE;
-- проверка в приложении
UPDATE items SET stock = 9 WHERE id = 1;
COMMIT;

Что хотят услышать

  • Сценарий потерянного обновления.
  • Атомарный UPDATE.
  • SELECT FOR UPDATE и оптимистическая версия.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Прочитать значение в приложении, вычесть и записать — это безопасно при любой нагрузке
  • ✗Достаточно добавить индекс на колонку, которую обновляют
  • ✓Параллельные записи затирают друг друга; спасают атомарный UPDATE, FOR UPDATE или версия строки
  • ✗Транзакция видит незафиксированные данные другой; спасает переход с Read Uncommitted на Read Committed

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования