Да. Они работают вместе, вы можете использовать @Version
без LockMode.OPTIMISTIC
, но вы не можете использовать LockMode.OPTIMISTIC
без @Version
.
С оптимистичной блокировкой, когда вы изменяете объект, столбец версии объекта увеличивается. Когда объект сохраняется, он гарантирует, что столбец версии является тем, что было, когда объект был впервые прочитан, а если нет, он выдает OptimisticLockException
(что обычно приводит к перезапуску транзакции).
Могут быть времена, когда вам нужно «изменить» сущность, не изменяя ее. Это, как правило, довольно редко. Например, представьте себе объект Foo
, который имеет поле mode
и объект Bar
, который имеет поле volume
. Если mode
- LOUD
, то volume
может быть 0-100. Если mode
- QUIET
, то volume
может быть только 0-10.
Это возможно с оптимистической блокировки, что вы можете получить в плохом состоянии, если один пользователь изменяет mode
(от LOUD
до QUIET
) в то же время другой пользователь изменяет volume
(от 5 до 50). Это связано с тем, что первый пользователь увеличивает и проверяет столбец версии объекта Foo
, а второй пользователь увеличивает его и проверяет столбец версии объекта Bar
.
Одним из решений для этого является функция changeVolume
для получения блокировки LockMode.OPTIMISTIC
на объекте Foo
. Это говорит Hibernate, что, хотя эта функция не изменяет объект Foo
, ему все еще нужно увеличивать и проверять поле версии.