Для механизма оптимистической блокировки по умолчанию, указанного в аннотации @Version
, такой риск отсутствует.
Как объясняется в этой статье , оптимистическая блокировка не требует никакойдополнительный SELECT для получения и проверки версии после изменения объекта.Итак, существует два шага:
Объект извлекается из БД вместе с его версией:
SELECT * FROM PRODUCT WHERE ID = 1;
ОБНОВЛЕНИЕ илиDELETE будет использовать версию, выбранную тем же SELECT, который выбрал сущность:
UPDATE PRODUCT SET (LIKES, QUANTITY, VERSION) = (5, 10, 3)
WHERE ID = 1 AND VERSION = 2;
Таким образом, Hibernate не проверяет версию сущности.БД проверяет это с помощью предложения WHERE.Hibernate проверяет только результат updateCount
вызова метода PreparedStatement.executeUpdate
.Если счетчик не равен updateCount
, это означает, что либо строка была удалена, либо версия имеет изменения, а это означает, что мы используем устаревшие данные, поэтому будет выдано OptimisticLockException
.
Следовательно, для оптимистической блокировки на основе @Version
не может возникнуть конфликтов, поскольку запись может быть изменена только одной транзакцией за раз, и как только строка заблокирована модификацией, блокировка будетсохраняется до тех пор, пока транзакция не завершится или не откатится.
Только явное LockModeType.OPTIMISTIC
может привести к условиям гонки, как описано в этой статье .Однако вы легко можете исправить это, используя пессимистическую общую или явную блокировку .