Ответ
Аннотация @Version в JPA используется для оптимистичной блокировки (optimistic locking). Она помогает предотвратить конфликты при одновременном изменении одной и той же сущности разными транзакциями.
Принцип работы:
- Поле с
@Versionавтоматически увеличивается при каждом обновлении сущности - Если две транзакции пытаются изменить одну запись, но имеют разное значение версии, выбрасывается
OptimisticLockException
Пример:
@Entity
public class Product {
@Id
private Long id;
@Version
private Long version;
// другие поля
}
Преимущества:
- Не блокирует данные на уровне БД
- Простота реализации
- Подходит для высоконагруженных систем
Используется обычно с числовыми полями (Long, Integer) или с Timestamp.
Ответ 18+ 🔞
А, ну это про ту самую аннотацию, которая как будто говорит: «Эй, пока ты тут свой SQL писал, кто-то уже успел эту запись обоссать!»
В общем, @Version — это такая хитрая жопа для оптимистичной блокировки. Представь: два потока лезут в одну и ту же сущность, как мартышки на банан. Без версии они бы друг другу нахуй всё перезаписали и даже не заметили. А с версией — начинается цирк.
Как это, блядь, работает:
- Вешаешь
@Versionна какое-нибудь числовое поле (обычноLongилиInteger). Это как татуировка «не трожь, моё». - Когда сущность впервые сохраняется, Hibernate ставит там, скажем, 0.
- Потом, когда ты её обновляешь, он автоматом, сука, увеличивает версию на единицу перед запросом UPDATE.
- И самый сок: этот UPDATE в БД выглядит не просто
UPDATE product SET name = 'Шляпа' WHERE id = 5, аUPDATE product SET name = 'Шляпа', version = 1 WHERE id = 5 AND version = 0. - И вот если второй поток уже успел обновить запись и сдвинул версию, то условие
WHEREне сработает — обновлено будет 0 строк. JPA это видит и орет: «Оп-па!» — швыряя тебе в рожуOptimisticLockException.
Вот тебе пример кода, чтоб глаза не разбегались:
@Entity
public class Product {
@Id
private Long id;
@Version
private Long version; // Вот этот самый сторожевой хуй
private String name;
// ... остальные поля
}
Плюсы всей этой движухи:
- Не блокирует БД наглухо. Никаких
SELECT FOR UPDATE, которые всё тормозят. Просто проверка версии и пошёл дальше. - Проще пареной репы. Написал одну аннотацию — и защита от дурака (точнее, от другого такого же потока) готова.
- Для нагрузки подходит. Когда запросов овердохуища, а конфликты редки — это то, что надо.
Используют обычно для числовых полей, но можно и Timestamp прикрутить, хотя с ним, блядь, мороки больше из-за точности времени. Короче, @Version — это как поставить на свою пивную кружку в баре замызганную бумажку с надписью «Не пить!». Работает, пока все адекватные.