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

Ответ

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

Аналогия: Прежде чем войти в комнату, вы запираете дверь снаружи, чтобы никто другой не мог войти, пока вы там находитесь.

Как это работает?

  1. Транзакция А запрашивает блокировку ресурса.
  2. Транзакция А получает блокировку и начинает работу с ресурсом.
  3. Транзакция Б пытается получить доступ к этому же ресурсу, но вынуждена ждать, пока Транзакция А не снимет блокировку.
  4. Транзакция А завершает работу и освобождает ресурс.
  5. Транзакция Б получает доступ.

Пример в SQL (PostgreSQL):

BEGIN;
-- Блокируем строку с id = 1 до конца транзакции
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;

-- Выполняем операции...
UPDATE accounts SET balance = balance - 100 WHERE id = 1;

COMMIT; -- Снимаем блокировку

Пример в Go с sync.Mutex:

var accountMutex sync.Mutex

func withdraw(amount int) {
    accountMutex.Lock()   // Захватываем мьютекс (блокируем)
    defer accountMutex.Unlock() // Гарантируем освобождение в конце функции

    // ... логика снятия средств (критическая секция) ...
}

Отличие от оптимистичной блокировки

Оптимистичная блокировка, наоборот, исходит из предположения, что конфликты маловероятны. Ресурс не блокируется. Вместо этого перед обновлением проверяется, не изменил ли кто-то другой данные за время их чтения.

  • Как работает: Используется версионирование (например, поле version или updated_at).
    1. Читаем данные вместе с их версией (например, version = 5).
    2. Выполняем вычисления.
    3. Пытаемся обновить данные с условием WHERE id = 1 AND version = 5.
    4. Если строка обновилась — отлично. Если нет (0 строк обновлено), значит, кто-то другой уже изменил данные (версия стала 6), и нашу транзакцию нужно повторить или отменить.
ХарактеристикаПессимистичная блокировкаОптимистичная блокировка
Основное допущениеКонфликты вероятныКонфликты маловероятны
МеханизмБлокировка ресурса перед операциейПроверка на изменения перед записью
ПроизводительностьНиже при малом количестве конфликтов (из-за ожидания)Выше при малом количестве конфликтов
СложностьРиск взаимоблокировок (deadlocks)Требует логики повторных попыток
Когда использоватьВысокая конкуренция за данные, цена конфликта высокаНизкая конкуренция, операции чтения преобладают над записью