как я могу обновить сущность синхронно в spring jpa

#spring #hibernate #spring-data-jpa

Вопрос:

у меня проблема : у меня есть объект продукта, у которого есть 2 столбца id и количество _ так что у меня есть 2 api

  • один для обновления это приведет к обновлению количества сущности продукта (количество = количество — 1)
  • один для обновления это обновит количество сущности продукта (количество = количество 1) проблема в том, что я вызываю 2 api одновременно, этот результат не мой ожидаемый вот моя диаграмма введите описание изображения здесь

кто-нибудь может помочь мне поблагодарить вас

Комментарии:

1. Вы вызываете оба Api одновременно ?? вы пробовали использовать пессимистическую блокировку(Pessimistic_write_lock) в spring jpa ?

2. что ж, я изучу это, спасибо за ваш ответ

Ответ №1:

Ну, для вашего конкретного сценария существует концепция, называемая блокировкой. И существует два типа блокировки

  1. Оптимистичный
  2. Пессимистический

Идея заключается в том, что когда одна транзакция обновляет строку таблицы БД, вы не должны позволять другой транзакции обновлять эту строку до тех пор, пока не будет зафиксирована предыдущая.

В приложении существует несколько способов достижения такого типа блокировки. Мы можем описать этот параллельный процесс обновления как столкновение. В системе, где столкновение происходит не очень часто, вы можете использовать подход с оптимизацией блокировки.

При оптимистическом подходе вы сохраняете version номер в своем ряду. Когда вы выполняете обновление, вы увеличиваете версию на 1. Давайте проанализируем ваш сценарий сейчас и вызовем две ваши службы I (увеличение) и D (уменьшение). У вас есть строка продукта P в таблице базы данных, где quantity = 3 , version = 0 . Когда I и D вызывается для них обоих, когда они извлекаются P из базы данных, состояние P выглядит следующим образом

количество = 3, версия = 0

Теперь D выполняется первым, уменьшите и сохраните P ваш запрос на обновление, как показано ниже

  UPDATE Product p set p.quantity = :newQuantity
, p.version = p.version   1 where p.version = :oldVersion and p.id = :id
 

Для случая D значения newQuantity = 2 (oldQty - 1) и значения oldVersion = 0 (мы выбрали его в начале)

Теперь текущее состояние P выглядит следующим образом

количество = 2, версия = 1

Теперь при I попытке выполнить вы должны сгенерировать тот же запрос на обновление, но для этого случая значение newQuantity = 4 (oldQty 1) и значение oldVersion = 0 (мы получили его в начале).

Если вы добавите эти значения в запрос на обновление, ваша строка не будет обновлена, так как часть проверки версии будет ложной. После этого вы можете создать любое исключение блокировки, чтобы уведомить своего клиента о том, что запрос не может быть завершен, и можете повторить попытку. Это в основном основная концепция оптимистичной блокировки, и есть гораздо более эффективные способы справиться с ней с помощью таких фреймворков, как Hibernate

Здесь вы можете заметить, что мы не отклоняли ни один из запросов на чтение во время обновления строки, но при Pessimistic блокировке вы отказываете в любом запросе на чтение, когда выполняется другая транзакция. Таким образом, в основном, когда D происходит процесс уменьшения I , вы не сможете прочитать значение, и оттуда вы можете вернуться к своему клиенту, сказав, что запрос не был завершен. Но этот подход требует затрат на чтение тяжелых таблиц в обмен на жесткую целостность данных.

Комментарии:

1. большое вам спасибо, сэр