Наталья Кайда 05 сентября 2025

🔒 Оптимистическая vs пессимистическая блокировка: как выбрать и не пожалеть

Что произойдет, если несколько пользователей одновременно начнут менять одни и те же данные? Скорее всего — потеря изменений и ошибки. Чтобы этого избежать, в системах используются блокировки: пессимистические — когда конфликтам не дают случиться, и оптимистические — когда система проверяет их только перед сохранением. Разбираемся, как работают блокировки и какая из них лучше подойдет вашему приложению.
🔒 Оптимистическая vs пессимистическая блокировка: как выбрать и не пожалеть

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

Если этого не делать, возникнут ошибки:

  • Потеря изменений (когда одно обновление затирает другое).
  • Чтение неактуальных (устаревших) данных.
  • Неожиданные данные в выборке (фантомные записи).

Чтобы этого избежать, используются механизмы блокировок. Блокировки бывают пессимистическими и оптимистическими.

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

Это стратегия, которая исходит из принципа «Лучше подстраховаться, чем пожалеть». Пессимистическая блокировка предполагает, что конфликт между пользователями скорее всего случится, и поэтому блокирует данные заранее, до того, как начнется редактирование.

Пессимистическая блокировка
Пессимистическая блокировка

Как работает пессимистическая блокировка:

  • Пользователь A открывает профиль клиента.
  • Система отправляет в базу запрос «выбери запись клиента с id = 101 и заблокируй ее для других на время редактирования»:
        SELECT * FROM customers WHERE id = 101 FOR UPDATE

    
  • База данных возвращает заблокированную запись. Теперь никто другой не сможет ее изменить, пока пользователь A не закончит редактирование.
  • Пользователь A редактирует, например, e-mail клиента.

Одновременно пользователь B:

  • Тоже пытается открыть этот же профиль клиента (id = 101).
  • Система отправляет точно такой же запрос:
        SELECT * FROM customers WHERE id = 101 FOR UPDATE

    

Но база данных видит, что запись уже заблокирована пользователем A, и задерживает выполнение. Пользователь B ждет, пока A закончит работу, либо запрос отвалится по тайм-ауту. Когда пользователь A нажимает «сохранить», система фиксирует изменения в базе и освобождает блокировку.

После этого пользователь B больше не блокируется. Его запрос отправляется снова, запись загружается уже с новыми изменениями, и он может начать свое редактирование.

Преимущества пессимистичной блокировки:

  • Гарантирует целостность данных. Конфликты исключаются заранее — никто не сможет работать с одними и теми же данными одновременно.
  • Подходит для критически важных данных — например, для банков, систем бронирования, учета товаров.

Недостатки:

  • Снижает конкурентность. Если кто-то заблокировал запись, другие пользователи не смогут даже посмотреть ее до освобождения.
  • При высокой загрузке (много пользователей) может привести к застоям и взаимным блокировкам (дедлокам), когда процессы ждут друг друга бесконечно.
  • При большом числе одновременных запросов производительность может сильно снижаться.

Когда использовать пессимитическую блокировку:

  • Одни и те же данные часто редактируют сразу несколько пользователей.
  • Важно избегать даже малейших конфликтов.
  • Потеря данных недопустима (например, при финансовых операциях).
💻 Библиотека программиста
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека программиста»

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

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

Вместо того чтобы сразу блокировать данные (как при пессимистичной блокировке), система разрешает свободный доступ и проверяет, не изменились ли данные, только в момент сохранения.

Оптимистическая блокировка
Оптимистическая блокировка

Как работает оптимистическая блокировка:

1️⃣ Чтение данных

  • Пользователь A открывает профиль клиента. Система загружает данные и вместе с ними — номер версии (например, version = 1).
  • Пользователь B делает то же самое: читает профиль клиента, тоже получает version = 1.

2️⃣ Редактирование

Оба пользователя параллельно редактируют одни и те же данные. Например, A меняет e-mail, B меняет имя.

3️⃣ Попытка сохранить изменения

  • Пользователь A нажимает «Сохранить».
  • Система проверяет: «Когда пользователь A загрузил профиль, была version = 1. Сейчас в базе тоже version = 1»?

Если версии совпадают:

  • Система разрешает обновление.
  • Записывает новые данные.
  • Повышает версию на 1 (теперь version = 2).

4️⃣ Конфликт при сохранении изменений, сделанных другим пользователем

  • Теперь пользователь B тоже нажимает «Сохранить» для своих изменений.
  • Система проверяет: «Когда пользователь B загружал профиль, была версия 1. Какая версия сейчас имеется в базе?»
  • Поскольку версии не совпадают (в базе уже version = 2), система понимает, что кто-то изменил данные раньше.
  • Возникает конфликт. Система отклоняет запрос и сообщает пользователю: «Запись изменилась с момента начала редактирования. Обновите страницу и попробуйте снова».

Плюсы оптимистической блокировки:

  • Высокая скорость работы и параллелизм — никто не ждет блокировок при чтении и редактировании.
  • Дедлоки не возникают — ведь блокировки почти не используются.
  • Отлично подходит для приложений, где записи с общим доступом читают часто, а редактируют редко (фиды соцсетей, корпоративные отчеты и дашборды).

Минусы:

  • Если нескольким юзерам нужно часто редактироватьт одни и те же данные — конфликты станут частыми, и пользователям придется постоянно обновлять страницу и начинать заново.
  • Иногда работа будет потеряна в последний момент, если кто-то другой успел сохранить изменения раньше.

Где чаще всего используют оптимистическую блокировку:

  • ORM-фреймворки (Hibernate, Entity Framework и др.)
  • Микросервисы и распределенные системы, где удержание блокировок обходится дорого.

Лучшие практики при использовании механизмов блокировки

Когда вы применяете пессимистическую или оптимистическую блокировку, важно правильно организовать работу с блоками, чтобы избежать проблем с производительностью и конфликтами. Вот несколько советов:

1️⃣ Держите блокировки как можно меньше по времени

Чем дольше удерживается блокировка, тем больше снижается параллельность работы программы. Это увеличивает риск конфликтов и взаимных блокировок.

2️⃣ Используйте блокировки с минимальным охватом

Блокируйте только то, что действительно необходимо. Например, если можно — блокируйте отдельные строки в таблице, а не всю таблицу. Это уменьшит количество ситуаций, когда разные процессы мешают друг другу.

3️⃣ Реализуйте логику повторной попытки (для оптимистической блокировки)

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

4️⃣ Следите и настраивайте поведение блокировок

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

5️⃣ Выбирайте стратегию в зависимости от характера данных

  • Если одни и те же записи часто обновляются разными пользователями, пессимистическая блокировка будет безопаснее, потому что она гарантирует, что только один пользователь сможет работать с записью в момент времени.
  • Если обновления редкие или распределены между разными записями, лучше использовать оптимистическую блокировку — она обеспечит более высокую производительность и меньше конфликтов.

Подведем итоги

Напоследок представим все нюансы блокировок в одной таблице:

Критерий Оптимистическая блокировка Пессимистическая блокировка
Идея Конфликты случаются редко Конфликты вероятны, лучше заранее заблокировать
Когда происходит проверка В момент сохранения изменений В момент чтения данных
Как работает Данные читаются и редактируются без блокировки, при сохранении проверяется версия При чтении ставится блокировка, пока ее не снимут — другие не могут редактировать запись
Конкурентность Очень высокая: множество пользователей может работать с одними и теми же данными Низкая: блокировка мешает другим редактировать одновременно
Риск конфликтов Конфликты проверяются в момент записи Конфликты исключены: блокировка заранее защищает от этого
Необходимость повторной попытки Часто требуется, если обнаружен конфликт Почти не требуется, если блокировка успешна
Задержки из-за блокировки Нет Могут быть: ожидание освобождения блокировки
Подходит для: Много чтения, мало изменений: аналитика, отчеты, соцсети Частые изменения одних и тех же данных: финансовые транзакции, инвентаризация
Плюсы Высокая производительность, нет дедлоков Гарантия защиты данных, простая логика при сохранении
Минусы Конфликты на этапе сохранения Потенциальные дедлоки, низкая масштабируемость

Комментарии

ВАКАНСИИ

Добавить вакансию
Lead C++ Software Engineer (Gameplay)
по итогам собеседования
AppSec BP
по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ