Что такое оптимистическая блокировка (optimistic locking) и как она реализуется?

«Что такое оптимистическая блокировка (optimistic locking) и как она реализуется?» — вопрос из категории Паттерны, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Принцип работы:

  1. Каждая версионируемая сущность (например, строка в БД) имеет поле-версию (обычно числовое или timestamp).
  2. При чтении данных клиент также получает текущее значение версии.
  3. При обновлении в запрос добавляется условие, что версия не изменилась с момента чтения: UPDATE table SET data = 'new', version = version + 1 WHERE id = ? AND version = ?.
  4. Если количество обновленных строк равно 0 (версия изменилась другим транзакцией), фиксируется оптимистическое исключение (например, OptimisticLockException в JPA). Приложение должно обработать его (например, повторить операцию).

Реализация с JPA/Hibernate:

@Entity
public class Account {
    @Id
    private Long id;
    private BigDecimal balance;

    @Version // Аннотация для включения оптимистической блокировки
    private Long version; // Поле автоматически инкрементится при каждом UPDATE
}

// В сервисе. При конфликте будет выброшено OptimisticLockException
@Transactional
public void updateBalance(Long accountId, BigDecimal newBalance) {
    Account account = entityManager.find(Account.class, accountId);
    account.setBalance(newBalance);
    // При коммите Hibernate выполнит UPDATE с проверкой version
}
Преимущества и недостатки: Преимущества Недостатки
Высокая масштабируемость, нет долгих блокировок Требует обработки конфликтов на уровне приложения
Уменьшает вероятность взаимных блокировок (deadlocks) Неэффективна при очень высокой конкуренции за одни данные
Простая реализация через ORM