Какво представляват Optimistic и Pessimistic locking в JPA / бази данни?
Това са два подхода за управление на едновременен достъп до данни (concurrency control), с цел да се избегнат проблеми като записване на остарели данни, конфликти между потребители и загуба на информация.
1. Optimistic Locking (Оптимистично заключване)
Идея:
Предполага се, че конфликти са малко вероятни и няколко потребители могат да четат и модифицират данни едновременно, без заключване. Конфликтът се открива чак при записване (commit).
Механизъм:
- Използва се специално поле, например:
@Version
- При всяка промяна на записа се инкрементира версията
- При
merge()
илиflush()
JPA проверява дали версията не се е променила междувременно - Ако се е променила → грешка (например
OptimisticLockException
)
Подходящо за:
- Web приложения
- REST API
- Данни, които рядко се променят от много потребители едновременно
Пример:
@Entity
public class Product {
@Id
private Long id;
private String name;
@Version
private int version; // JPA ще следи тази версия
}
Ако двама потребители заредят един и същ обект:
- И двамата получават версия 1
- Първият потребител го променя →
version = 2
и записва успешно - Вторият се опитва да го запише със
version = 1
→ конфликт → изключение
2. Pessimistic Locking (Песимистично заключване)
Идея:
Предполага се, че конфликти са вероятни, затова данните се заключват предварително, така че други потребители не могат да ги променят докато трае операцията.
Механизъм:
- Явно задаване на lock при четене на данни
- Използват се SQL механизми като
SELECT FOR UPDATE
- JPA: чрез
LockModeType.PESSIMISTIC_WRITE
илиPESSIMISTIC_READ
Подходящо за:
- Банкови транзакции
- Инвентаризация
- Системи, където всеки запис е критичен и конфликтите са чести
Пример:
Product product = em.find(Product.class, id, LockModeType.PESSIMISTIC_WRITE);
product.setName("New name");
Сравнение:
Характеристика | Optimistic Locking | Pessimistic Locking |
---|---|---|
Предположение | Рядко има конфликти | Конфликтите са вероятни |
Заключване при четене | Не | Да (SQL lock) |
Производителност | По-висока | По-ниска |
Конфликти | Хващат се при commit | Избягват се чрез lock |
Използване | @Version | LockModeType.PESSIMISTIC_* |
Как да избера?
Тип на приложение | Подходящ метод |
---|---|
REST API, Web фронт | Optimistic locking |
Складова система, POS | Pessimistic locking |
Банкови трансфери | Pessimistic locking |
Платформи с малко записващи операции | Optimistic locking |