У меня есть некоторые запутанные вещи о JPA.
Насколько я знаю, JPA имеет контекст персистентности (он же кеш L1) и управляет всеми объектами для персистентности. и управляет сущностью с помощью описанного ниже процесса.
1. когда происходит запрос на поиск, в контексте отсутствует сущность, поэтому менеджер сущностей запрашивает данные в базе данных
2. сохранить результат как сущности в постоянном тексте.
3. после этого, когда запрос происходит, запрос постоянства возвращает объекты памяти, если они есть.
Но в-третьих, это довольно запутанно, как это работает в среде нескольких экземпляров. Я думаю, что в нескольких экземплярах приложения он не может обеспечить одинаковые данные сущности во всех экземплярах.
Предположим, что есть 2 экземпляра приложения JPA (все экземпляры имеют одинаковую логику для распределения нагрузки). Таблица имеет 2 столбца, один - id, первичный ключ, а другой - имя varchar.
Есть строка с id = 1, name = "foobar"
«экземпляр A» генерирует сущность с идентификатором, равным 1, из базы данных по запросу пользователя.
также "экземпляр B" генерирует ту же сущность с идентификатором, равным 1, из базы данных по запросу пользователя.
и затем «экземпляр A» обновляет объект с ID = 1 до name = «blahblah» по запросу пользователя на обновление.
По прошествии достаточного количества времени спустя без запроса к обоим экземплярам, если запрос на обновление, который представляет собой «имя обновления, устанавливает новое имя из таблицы, где name = blahblah», возникает в «экземпляре B», я запутался, у него уже есть сущность и ее имя не может быть обновлено до «бла». Итак, как работает последний запрос на обновление в JPA?
EDIT
Я понял, что мой вопрос не ясен. Поскольку JPA выполняет запрос БД к СУБД, когда транзакция была принята, обычно не возникает проблем с количеством приложений.
Чтобы рассказать вам, почему я спрашиваю об этом, давайте предположим, что ниже приведен код.
void updateEntities() {
entityManager.getTransaction().begin();
List<MyEntity> entities = dao.findAll(); // point1
for (MyEntity e : entities) {
e.setValue(e.getValue() + 100); // point2
}
entityManager.getTransaction().commit();
}
List<MyEntity> findMyEntities() {
return dao.findAll(); // point3
}
Два экземпляра, в коде которых есть вышеуказанный блок кода (оба являются одинаковыми экземплярами кода для распределения нагрузки). (а количество объектов достаточно для оперативной памяти.)
когда A instance
генерирует сущности в памяти, когда по запросу клиента вызывается метод findMyEntities
.
затем следующий запрос был получен клиентом, затем запрос достиг instance B
, и instance B
также сгенерировал все объекты в памяти.
а затем запрос на обновление достиг instance A
, и экземпляр, выполняющий updateEntities, и все объекты в памяти instance A
были обновлены.
но в это время, есть разница между кэшированными объектами instance A
и instance B
кэшированными объектами. Но instance B
может не знать, были ли обновлены данные, или нет.
Так что мне стало интересно, когда запрос на обновление произойдет до instance B
после описанной выше ситуации, я считаю, как показано ниже
- запрос пользователя произошел. поэтому будет вызван метод
updateEntities
.
- в точке 1, JPA немедленно выполнила реальный запрос для дБ и синхронизировала результат запроса с контекстом объекта.
- кодовый блок point2 выполняется нормально.
Это правильно?