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

Чем отличается оптимистичная блокировка от пессимистичной?

MiddleТранзакции и изоляцияSQLHibernate / JPA
Ещё спрашивают так:
  • Как работает @Version в JPA?
  • Когда использовать SELECT FOR UPDATE?
Коротко

Пессимистическая — блокируем строку заранее (SELECT ... FOR UPDATE), остальные ждут. Оптимистическая — не блокируем, а при записи проверяем версию (WHERE version = ?); не совпала — конфликт, повторяем.

  • Частые конфликты и короткие транзакции — пессимистическая
  • Редкие конфликты и долгое «думание» (форма редактирования) — оптимистическая
  • В JPA: @Version и OptimisticLockException; @Lock(PESSIMISTIC_WRITE)

А ещё Для счётчиков лучше атомарный UPDATE ... SET x = x - 1 WHERE x > 0

Попробуйте сами

Уровни изоляции: версии строк, снимки и аномалии

Подробно

Пессимистическая блокировка исходит из того, что конфликт вероятен: SELECT ... FOR UPDATE блокирует строки до конца транзакции, другие транзакции с FOR UPDATE ждут. Просто и надёжно, но блокировки держатся всё время транзакции, возможны дедлоки при захвате нескольких строк, и нельзя держать блокировку, пока пользователь думает. Варианты: NOWAIT (сразу ошибка), SKIP LOCKED (очереди задач в таблице).

Оптимистическая блокировка считает конфликты редкими. В строке есть колонка version; при обновлении: UPDATE ... SET ..., version = version + 1 WHERE id = ? AND version = ?. Если обновлено 0 строк — кто-то изменил раньше: перечитать и повторить или показать конфликт пользователю. Работает между HTTP-запросами (ETag и If-Match), не держит блокировок.

Выбор:

  • конфликты часты (горячая строка) — пессимистическая, иначе оптимистическая будет постоянно откатываться;
  • пользователь редактирует данные минутами — только оптимистическая;
  • простое изменение счётчика — ни та, ни другая: атомарный UPDATE.

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

  • Механика обеих блокировок.
  • Критерий выбора: частота конфликтов и длительность.
  • Поддержка в JPA.
  • Атомарный UPDATE как альтернатива — плюс.

Частые ошибки

  • Держать FOR UPDATE во время внешних вызовов.
  • Не обрабатывать OptimisticLockException.

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

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

Показать варианты и ответ
  • ✗Оптимистическая блокирует таблицу целиком, пессимистическая — только одну строку
  • ✓Пессимистическая блокирует строку заранее; оптимистическая проверяет версию при записи
  • ✗Пессимистическая выбирается при редких конфликтах и долгом редактировании формы пользователем, оптимистическая — при частых
  • ✗Обе блокируют строку, разница только в длительности

Что спросят дальше

  • Как реализуется @Version в JPA?
  • Как избежать deadlock при FOR UPDATE?

Разбор темы

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

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

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

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

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