Ответ
Оптимистическая блокировка выгодна в высокопроизводительных приложениях с низкой вероятностью конфликта параллельных изменений одних и тех же данных (read-heavy или low-contention сценарии).
Принцип работы:
Механизм не блокирует запись на уровне БД. Вместо этого каждая сущность имеет поле-версию (обычно @Version). При чтении запоминается значение версии. При попытке обновления в WHERE-условие добавляется проверка, что версия не изменилась. Если она изменилась (значит, данные уже обновили), выбрасывается OptimisticLockException.
Пример реализации в JPA:
@Entity
public class BankAccount {
@Id
private Long id;
private BigDecimal balance;
@Version
private Long version; // Hibernate автоматически увеличивает эту версию при каждом UPDATE
}
// В сервисе. Если два потока попытаются обновить один счет,
// второй получит OptimisticLockException.
@Transactional
public void withdraw(Long accountId, BigDecimal amount) {
BankAccount account = entityManager.find(BankAccount.class, accountId);
account.setBalance(account.getBalance().subtract(amount));
// При коммите выполнится SQL: UPDATE account SET balance=?, version=?
// WHERE id=? AND version=? (проверка старой версии)
}
Преимущества:
- Высокая пропускная способность (throughput): Отсутствуют блокировки, читающие транзакции не ждут.
- Улучшенная масштабируемость.
Недостатки и требования:
- Необходима обработка конфликтов (retry-логика или уведомление пользователя).
- Плохо подходит для сценариев с высокой конкуренцией за запись (high-contention), например, обновление счётчика последнего номера заказа. В таких случаях лучше подходит пессимистическая блокировка (
SELECT ... FOR UPDATE).