Что такое оптимистичные и пессимистичные блокировки и в чем их разница
Что проверяют
Понимаете ли вы, что выбор зависит от вероятности конфликта, и знаете ли, как каждая реализуется.
Как отвечать
Пессимистичная: исходим из того, что конфликт вероятен, поэтому строку блокируем сразу при чтении. В SQL это SELECT ... FOR UPDATE, в JPA LockModeType.PESSIMISTIC_WRITE. Остальные ждут. Плюс в том, что конфликта не будет вовсе; минус в том, что ожидание съедает пропускную способность и появляется риск взаимной блокировки.
Оптимистичная: исходим из того, что конфликт редок, поэтому ничего не блокируем. У строки есть версия, и при записи проверяется, что она не изменилась:
update jobs set title = $1, version = version + 1
where id = $2 and version = $3;Обновлено ноль строк, значит кто-то успел раньше, и приложение обязано это обработать. В JPA это поле с @Version, а конфликт приходит как OptimisticLockException.
Как выбирать: короткая операция и редкие конфликты это оптимистичная, она дешевле и не держит блокировок. Высокая конкуренция за одну строку (остаток на складе, баланс) это пессимистичная, иначе половина попыток будет откатываться и повторяться.
Отдельно стоит сказать, что оптимистичная блокировка требует стратегии на конфликт: повторить операцию, показать пользователю, что данные изменились, или слить изменения. Без этого она превращается в случайные ошибки.
Где спотыкаются
Не знают, что оптимистичная блокировка это не блокировка вовсе, а проверка версии.
Забывают про обработку конфликта и отдают пользователю пятисотку.
Ставят FOR UPDATE на длинную транзакцию с внешним вызовом внутри и вешают всех остальных.
Путают это с уровнями изоляции: изоляция про видимость данных, блокировки про конкурирующую запись.