Вопрос проверяет понимание механизмов управления конкурентным доступом к данным в JPA, что критично для обеспечения целостности данных в многопользовательских приложениях.
JPA (Java Persistence API) предоставляет механизмы для управления одновременным доступом к одним и тем же данным, что предотвращает потерю обновлений и обеспечивает согласованность. Основная идея — контролировать, как несколько транзакций взаимодействуют с одной сущностью.
Этот подход основан на предположении, что конфликты при одновременном обновлении данных случаются редко. Вместо физической блокировки строки в базе, он использует поле версии (обычно аннотированное @Version). При каждом обновлении сущности значение версии увеличивается. Перед сохранением изменений JPA проверяет, не изменилась ли версия с момента чтения сущности. Если версия отличается, выбрасывается исключение OptimisticLockException.
@Entity
public class Product {
@Id
private Long id;
private String name;
@Version
private Long version; // Поле для оптимистической блокировки
// геттеры и сеттеры
}Применяется в сценариях с высокой конкурентностью на чтение, где обновления относительно редки, например, в каталогах товаров или системах с преимущественно просмотром данных.
Этот подход предполагает, что конфликты вероятны, и заранее блокирует запись для других транзакций. Блокировка устанавливается на уровне базы данных при чтении сущности и удерживается до конца текущей транзакции. В JPA её можно применить с помощью метода EntityManager.lock() или указания LockModeType в запросе.
// Блокировка сущности при поиске
Product product = em.find(Product.class, productId, LockModeType.PESSIMISTIC_WRITE);
// Или блокировка уже загруженной сущности
em.lock(product, LockModeType.PESSIMISTIC_WRITE);Основные типы пессимистических блокировок: PESSIMISTIC_READ (разделяемая блокировка, другие могут читать, но не изменять) и PESSIMISTIC_WRITE (эксклюзивная блокировка, другие не могут ни читать, ни изменять, в зависимости от СУБД). Применяется в критических операциях, где целостность данных важнее производительности, например, при списании остатков на складе или финансовых транзакциях.
Вывод: Оптимистическая блокировка подходит для сценариев с низкой вероятностью конфликтов, обеспечивая лучшую производительность. Пессимистическая блокировка необходима, когда конфликты часты и данные должны быть строго защищены от одновременных изменений, ценой потенциального снижения скорости работы из-за ожидания разблокировки.