0Pricing
SQL Academy · Урок

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

Сравните SELECT ... FOR UPDATE (пессимистический подход) и шаблоны с версией столбца / WHERE updated_at = ? (оптимистический подход)

«Оптимистическая и пессимистическая блокировка» — бесплатный урок SQL Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.

Две стратегии работы с параллельностью

  • Пессимистичная — блокировать строку при чтении; никто другой не сможет ее изменить
  • Оптимистичная — не блокировать строку, а при обновлении проверять, что она не изменилась

Пессимистичная стратегия: SELECT ... FOR UPDATE

Заблокировать сейчас, записать позже:

BEGIN;
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;
-- other transactions cannot lock or update this row
-- compute new balance...
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;

FOR SHARE

Блокировка для чтения — другие могут читать, но не могут записывать:

SELECT * FROM orders WHERE id = 1 FOR SHARE;
-- others can SELECT FOR SHARE but cannot UPDATE

Плюсы и минусы пессимистичной стратегии

Плюсы: легко рассуждать о поведении, повторные попытки не нужны.
Минусы: снижает параллельность, может вызвать ожидание блокировок и взаимные блокировки.

Оптимистичная стратегия: столбец версии

Читайте строку вместе с версией, а записывайте с условием WHERE version = expected:

BEGIN;
SELECT id, balance, version FROM accounts WHERE id = 1;
-- compute new balance...
UPDATE accounts
   SET balance = ?, version = version + 1
WHERE id = 1 AND version = ?;
-- check rows affected: 0 means someone else updated, retry

Оптимистичная стратегия с updated_at

Та же идея, но вместо явного столбца версии используется updated_at:

UPDATE accounts
   SET balance = ?, updated_at = NOW()
WHERE id = ? AND updated_at = ?;

-- If updated_at has changed in the meantime, 0 rows affected — retry.

Плюсы и минусы оптимистичной стратегии

Плюсы: высокая параллельность, отсутствие ожидания.
Минусы: запись может завершиться с ошибкой и потребовать повторной попытки; конфликт обнаруживается только во время UPDATE.

Когда выбирать пессимистичную стратегию

Используйте ее для:

  • Коротких транзакций с высокой конкуренцией за горячие строки
  • Денежных переводов — частично выполненная операция недопустима
  • Длительных операций, при которых конфликт вероятен

Когда выбирать оптимистичную стратегию

Используйте ее для:

  • Рабочих нагрузок преимущественно на чтение с редкими конфликтами
  • API без состояния, где клиент удерживает строку между запросами
  • Редактирования на мобильном устройстве или в автономном режиме с последующей синхронизацией

Гибридный подход: FOR UPDATE NOWAIT

Попробуйте установить блокировку; если строка уже заблокирована, немедленно завершитесь с ошибкой и предложите пользователю повторить попытку:

SELECT * FROM accounts WHERE id = 1 FOR UPDATE NOWAIT;
-- ERROR if someone else holds it — user sees a friendly retry message

Консультативные блокировки

Блокировки на уровне приложения, не связанные с какой-либо строкой:

SELECT pg_try_advisory_xact_lock(hashtext('order:42'));
-- True if you got the lock, false otherwise — useful for cross-row coordination.

Не забывайте индексировать цели блокировок

FOR UPDATE без индекса по столбцу в WHERE может заблокировать больше строк, чем ожидалось (блокируются просканированные строки, а не только соответствующие условию).

Тайм-ауты блокировок

Установите lock_timeout, чтобы не ждать бесконечно:

SET lock_timeout = '5s';
BEGIN;
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;
-- ERROR if lock not acquired in 5 seconds

Итоги

Пессимистичная стратегия блокирует строку, а оптимистичная проверяет ее при записи.

  • Пессимистичная: FOR UPDATE — просто, но снижает параллельность
  • Оптимистичная: столбец версии — выше параллельность, но нужны повторные попытки
  • Выбирайте стратегию в зависимости от рабочей нагрузки и при необходимости сочетайте их

Быстрая проверка

Уменьшение запасов товара в интернет-магазине сопровождается высокой конкуренцией. Какая стратегия блокировок обычно безопаснее?

Часто задаваемые вопросы

Урок «Оптимистическая и пессимистическая блокировка» бесплатный?

Да — полный текст урока «Оптимистическая и пессимистическая блокировка» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.

Чему я научусь в уроке «Оптимистическая и пессимистическая блокировка»?

Сравните SELECT ... FOR UPDATE (пессимистический подход) и шаблоны с версией столбца / WHERE updated_at = ? (оптимистический подход) Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать SQL Academy?

Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Оптимистическая и пессимистическая блокировка»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке SQL Academy?

Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Свойства ACID и аномалии
  2. Уровни изоляции: READ COMMITTED, REPEATABLE READ, SERIALIZABLE
  3. Взаимные блокировки: обнаружение и предотвращение
  4. Оптимистическая и пессимистическая блокировка
← Назад к SQL Academy