Что нужно учитывать при использовании пессимистичных блокировок в СУБД?

«Что нужно учитывать при использовании пессимистичных блокировок в СУБД?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Пессимистичная блокировка предполагает явную блокировку данных (строки, таблицы) на время транзакции для предотвращения конфликтов. Ключевые аспекты:

1. Влияние на производительность и параллелизм:

  • Снижает конкурентный доступ, так как блокирует данные для других транзакций.
  • Может стать узким местом в высоконагруженных системах.

2. Риск взаимоблокировок (Deadlock):

  • Возникает, когда две и более транзакции блокируют ресурсы в разном порядке.
  • Миттигация: Всегда блокируйте ресурсы в единой, предопределенной последовательности.

3. Управление блокировками:

  • Таймауты: Всегда задавайте разумный LOCK_TIMEOUT, чтобы избежать бесконечного ожидания.
  • Уровень изоляции: Часто используется с REPEATABLE READ или SERIALIZABLE.
  • Тип блокировки: PESSIMISTIC_READ (для чтения) vs PESSIMISTIC_WRITE (для изменения).

Пример в JPA:

entityManager.find(Product.class, productId, LockModeType.PESSIMISTIC_WRITE);
// или с таймаутом (в миллисекундах)
Map<String, Object> properties = Map.of("javax.persistence.lock.timeout", 5000);
entityManager.find(Product.class, productId, LockModeType.PESSIMISTIC_WRITE, properties);

4. Область применения:

  • Используйте для: Коротких операций с высокой конкуренцией за одни данные, где оптимистичная блокировка приводит к частым OptimisticLockException.
  • Избегайте для: Долгих операций или операций чтения, где подходит PESSIMISTIC_READ или snapshot isolation.