Что такое Optimistic Locking (Оптимистичная блокировка) в Spring Data JPA?

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

Ответ

Optimistic Locking — это стратегия управления конкурентным доступом к данным, которая предполагает, что конфликты при одновременном обновлении редки. Вместо физической блокировки записи на уровне БД используется контроль версий.

Реализация через @Version:

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

    @Version // Ключевая аннотация
    private Long version; // Поле для контроля версии
}

Как работает:

  1. Чтение: При загрузке сущности JPA сохраняет значение поля version.
  2. Обновление: При сохранении (merge/flush) JPA добавляет в WHERE-условие проверку на текущую версию:
    UPDATE account SET balance=?, version=? WHERE id=? AND version=?;
  3. Конфликт: Если количество обновлённых строк = 0 (значит, версия изменилась другим транзакцией), JPA выбрасывает OptimisticLockException.

Обработка конфликта:

@Transactional
public void transfer(Long accountId, BigDecimal amount) {
    try {
        Account acc = accountRepository.findById(accountId).orElseThrow();
        acc.withdraw(amount);
        accountRepository.save(acc);
    } catch (OptimisticLockException e) {
        // Стратегия повтора (retry) или уведомление пользователя
        throw new ConcurrentModificationException("Данные были изменены. Попробуйте снова.");
    }
}
Плюсы и минусы: Плюсы Минусы
Высокая производительность (нет долгих блокировок) Требует обработки исключений на уровне приложения
Масштабируемость Не подходит для сценариев с частыми конфликтами (например, инвентаризация последнего товара)
Избегает взаимных блокировок (deadlocks)

Альтернатива: Pessimistic Locking (LockModeType.PESSIMISTIC_WRITE), который блокирует запись на уровне БД.