← Назад к вопросам

Как работает Pessimistic Locking?

1.7 Middle🔥 141 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Pessimistic Locking в Java

Pessimistic Locking — это стратегия блокировки данных, которая исходит из предположения, что конфликты при одновременном доступе часто случаются. Поэтому блокировка захватывается заранее, до выполнения операции, и удерживается до завершения транзакции.

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

Пессимистический подход действует следующим образом:

1. Транзакция A начинает работу
2. Транзакция A БЛОКИРУЕТ строку в базе данных
3. Никакая другая транзакция не может читать или изменять эту строку
4. Транзакция A выполняет свои операции
5. Транзакция A коммитит и ОСВОБОЖДАЕТ блокировку
6. Другие транзакции получают доступ к данным

Реализация в JPA/Hibernate

import org.hibernate.LockMode;
import jakarta.persistence.*;

@Entity
@Table(name = "accounts")
public class Account {
    @Id
    private Long id;
    
    private String accountNumber;
    private BigDecimal balance;
    
    @Version
    private Long version;
}

@Service
public class AccountService {
    @Autowired
    private EntityManager entityManager;
    
    @Transactional
    public void transferMoney(Long fromAccountId, Long toAccountId, BigDecimal amount) {
        Account fromAccount = entityManager.find(
            Account.class,
            fromAccountId,
            LockModeType.PESSIMISTIC_WRITE
        );
        
        Account toAccount = entityManager.find(
            Account.class,
            toAccountId,
            LockModeType.PESSIMISTIC_WRITE
        );
        
        if (fromAccount.getBalance().compareTo(amount) >= 0) {
            fromAccount.setBalance(fromAccount.getBalance().subtract(amount));
            toAccount.setBalance(toAccount.getBalance().add(amount));
        }
    }
}

Типы блокировок

PESSIMISTIC_READ — разделяемая блокировка

  • Позволяет другим транзакциям читать
  • Запрещает изменять
  • SQL: SELECT ... FOR SHARE

PESSIMISTIC_WRITE — исключительная блокировка

  • Запрещает читать и изменять
  • SQL: SELECT ... FOR UPDATE

PESSIMISTIC_FORCE_INCREMENT — исключительная блокировка с инкрементом версии

Практический пример: Резервирование товара

@Service
public class InventoryService {
    @Transactional
    public boolean reserveProduct(Long productId, int quantity) {
        Product product = entityManager.find(
            Product.class,
            productId,
            LockModeType.PESSIMISTIC_WRITE
        );
        
        if (product != null && product.getAvailableQuantity() >= quantity) {
            product.setAvailableQuantity(product.getAvailableQuantity() - quantity);
            return true;
        }
        
        return false;
    }
}

Преимущества

  • Гарантирует отсутствие race conditions
  • Предотвращает lost updates
  • Простая для понимания логика
  • Эффективна при частых конфликтах

Недостатки

  • Может привести к deadlock'ам
  • Снижает параллелизм (другие транзакции ждут)
  • Может быть неэффективна при редких конфликтах
  • Требует тщательного управления порядком захвата блокировок