Разница между LockModeType Jpa
я смущен работой LockModeTypes в JPA:
-
LockModeType.Optimistic
- он увеличивает версию во время фиксации.
- вопрос здесь: Если у меня есть столбец версии в моей сущности, и если я не указываю этот режим блокировки, то он также работает аналогично, то в чем его польза?
-
LockModeType.OPTIMISTIC_FORCE_INCREMENT
- здесь он увеличивает столбец версии, хотя сущность не обновляется.
- но какая польза от него, если какой-либо другой процесс обновил ту же строку до фиксации этой транзакции? эта транзакция в любом случае потерпит неудачу. так в чем же польза этого
LockModeType
.
-
LockModeType.PESSIMISTIC_READ
- этот режим блокировки выдает
select for update nowait
(если тайм-аут подсказки не указан).. - таким образом, в основном это означает, что никакая другая транзакция не может обновить эту строку, пока эта транзакция совершено, то его в основном блокировка записи, почему его назвали
Read
замок?
- этот режим блокировки выдает
-
LockModeType.PESSIMISTIC_WRITE
- этот режим также выдает
select for update nowait
(если тайм-аут подсказки не указан). - вопрос вот в чем разница между этим режимом блокировки и
LockModeType.PESSIMISTIC_READ
как я вижу, оба пожара одинаковые запросы?
- этот режим также выдает
-
LockModeType.PESSIMISTIC_FORCE_INCREMENT
- это
select for update nowait
(если тайм-аут подсказки не указан) а также увеличивает номер версии. - я совершенно не понял, как это использовать.
- почему требуется увеличение версии, если
for update no wait
есть?
- это
1 ответов
я бы сначала различил оптимистические и пессимистические замки, потому что они отличаются по своему основному механизму.
Оптимистическая блокировка полностью контролируется JPA и требует только дополнительного столбца версии в таблицах DB. Он полностью не зависит от базового движка БД, используемого для хранения реляционных данных.
С другой стороны, пессимистическая блокировка использует механизм блокировки, предоставляемый базовой базой данных для блокировки существующих записей в таблицах. JPA необходимо знать, как запускать эти блокировки, а некоторые базы данных не поддерживают их или только частично.
теперь к списку типов замков:
-
LockModeType.Optimistic
- это действительно значение по умолчанию. Обычно он игнорируется, как указано ObjectDB. На мой взгляд, он существует только для того, чтобы вы могли динамически вычислять режим блокировки и передавать его дальше, даже если блокировка будет оптимистичной в конце. Не очень вероятный usecase, хотя, но это всегда хороший дизайн API, чтобы предоставить возможность ссылаться даже значение по умолчанию.
-
пример:
LockModeType lockMode = resolveLockMode(); A a = em.find(A.class, 1, lockMode);
-
LockModeType.OPTIMISTIC_FORCE_INCREMENT
- это редко используемый вариант. Но это может быть разумно, если вы хотите заблокировать ссылку на этот объект другим объектом. Другими словами, вы хотите заблокировать работу с сущностью, даже если она не изменена, но другие сущности могут быть изменены в отношение к этой сущности.
- пример: у нас есть книга и полка сущности. Можно добавить книгу на полку, но книга не имеет никакой ссылки на свою полку. Разумно заблокировать действие перемещения книги на полку, чтобы книга не оказалась на другой полке (из-за другой транзакции) до окончания этой транзакции. Чтобы заблокировать это действие, недостаточно заблокировать текущий объект книжной полки, так как книга еще не должна быть на полке. Это также не имеет смысла чтобы заблокировать все целевые книжные полки, так как они, вероятно, будут отличаться в разных транзакциях. Единственное, что имеет смысл, - это заблокировать саму книжную сущность, даже если в нашем случае она не изменяется (она не содержит ссылки на свою книжную полку).
-
LockModeType.PESSIMISTIC_READ
- этот режим похож на
LockModeType.PESSIMISTIC_WRITE
, но разные в одном: пока блокировка записи не будет установлена на том же объекте какой-либо транзакцией, она не должна блокировать чтение сущность. Он также позволяет блокировать другие транзакции с помощьюLockModeType.PESSIMISTIC_READ
. Различия между блокировками записи и чтения хорошо объяснены здесь (ObjectDB) и здесь (OpenJPA).
- этот режим похож на
-
LockModeType.PESSIMISTIC_WRITE
- это более сильная версия
LockModeType.PESSIMISTIC_READ
. КогдаWRITE
блокировка на месте, JPA с помощью базы данных предотвратит любую другую транзакцию для чтения сущности, а не только для записи как сREAD
замок. - способ, как это реализуется провайдером ina JPA в сотрудничестве с базовой БД, не предписан. В вашем случае с Oracle, я бы сказал, что Oracle не дает что-то близкое к
READ
замок.SELECT...FOR UPDATE
скорееWRITE
замок. Это может быть ошибка в спящем режиме или просто решение, которое вместо реализации пользовательского "мягче"READ
блокировка, тем "жестче"WRITE
вместо этого используется блокировка. Это в основном не нарушает согласованность, но не содержит всех правил сREAD
замки. Вы можете запустить несколько простых тестов с помощьюREAD
блокировки и длительные транзакции, чтобы узнать, могут ли другие транзакции приобретатьREAD
блокирует тот же объект. Это должно быть возможно, тогда как не сWRITE
замки.
- это более сильная версия
-
LockModeType.PESSIMISTIC_FORCE_INCREMENT
- это еще один редко используемый режим блокировки. Тем не менее, это вариант, где вам нужно объединить
PESSIMISTIC
иOPTIMISTIC
механизмы. С помощью равнинаPESSIMISTIC_WRITE
не в следующей ситуации:- транзакция A использует оптимистическую блокировку и считывает сущность E
- транзакция B получает блокировку записи на сущности E
- транзакция B фиксирует и освобождает блокировку E
- транзакция a обновляет E и совершает
- на шаге 4, Если столбец версии не увеличивается транзакцией B, ничто не мешает A перезаписать изменения режима B. Lock
LockModeType.PESSIMISTIC_FORCE_INCREMENT
заставит транзакция B для обновления номера версии и сбоя транзакции A с помощьюOptimisticLockException
, хотя B использовал пессимистическую блокировку.
- это еще один редко используемый режим блокировки. Тем не менее, это вариант, где вам нужно объединить