#java #sql #hibernate #jpa #transactions
#java #sql #переход в спящий режим #jpa #транзакции
Вопрос:
Предположим, мы используем базу данных с уровнем изоляции, установленным на: read_committed, и мы также используем объекты JPA, аннотированные с помощью @Version
.
У нас есть две транзакции T и K, подобные этим:
T ————————————- K
начните
читать A
, читать B
, читать C
————————————— начать
————————————— обновить A
————————————— завершите
обновление C
с использованием состояний
объекта A и B
end
На данном этапе транзакции T обновление C выполнено успешно (проверка версии в порядке), поэтому мы обновляем C, используя статус, который на самом деле никогда не существовал в базе данных.
Что не так с моим пониманием?
Редактировать:
@Vlad
Рассмотрим этот пример:
T—————————————————— K
Запустите транзакцию
прочитайте
———————————————— Запустить транзакцию
———————————————— Мод A
———————————————— Мод B
———————————————— Завершение транзакции
чтение версии C = 1
чтение B
// используйте данные da A и B
// для обновления C
A, B -> C
// обновление выполнено успешно (проверьте версию в порядке)
Завершить транзакцию
Используя OPTIMISTIC_FORCE_INCREMENT, вы, по сути, говорите мне всегда использовать метод find с правильно установленным параметром?
Ответ №1:
Оптимистичная блокировка работает только для отдельных строк таблицы. В этом конкретном случае объект C
может быть успешно обновлен, поскольку вторая транзакция его не изменяет.
Если вы хотите создать здесь конфликт, то вы должны использовать любой из следующих запросов оптимистичной блокировки:
Таким образом, во второй транзакции всякий раз, когда вы обновляете объект A
, вы также запускаете увеличение версии в C
.
Комментарии:
1. Большое вам спасибо!
2. Я думаю, что это не нужно, но я был бы рад услышать от вас об этом?
3. Сброс вызывается автоматически в конце транзакции, поэтому вам не нужно вызывать его вручную.
4. У меня есть последнее сомнение: предположим, мы загружаем объект en с hibernate findById с параметром OPTIMISTIC_FORCE_INCREMENT и сериализуем объект клиенту (здесь долгий разговор), когда клиент возвращает серверу объект, должен ли я создать присоединенный объект, вручную установить для него версию и затем вызвать merge ? извините, что беспокою вас 😉
5. Вы узнаете гораздо больше, когда попробуете все эти примеры с помощью упражнений. Для этого используйте мой репозиторий на GitHub . Удачи!