Подтвердить что ты не робот

Когда использовать EntityManager.clear()?

Пользовательский класс сопоставления JPA имеет метод:

removeUser()

1. execute 'DELETE' HQL query to remove user
2. call getEntityManager().flush();
3. call getEntityManager().clear();

Если я правильно понимаю clear(), он удалит из контекста все постоянные объекты. - источник

Однако я также читал здесь,

you should define clear architecture- and design guidelines about where a 
clear() can be called. 

Каковы четкие указания о том, когда нужно вызывать clear()?

4b9b3361

Ответ 1

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

  • при выполнении пакетной обработки, чтобы избежать гигантского кеша, хранящего память, и увеличения времени на флеш из-за длительных грязных проверок.
  • когда вы выполняете запросы DML или SQL, которые полностью обходят кеш-менеджер сущности (как в вашем примере). В этом случае состояние, хранящееся в кэше, не отражает то, что находится в базе данных из-за запросов, поэтому вы хотите очистить кеш, чтобы избежать этой несогласованности.

Ответ 2

Да, это точно зависит от стиля архитектуры платформы как точек документации.

  • Например, если в вашем приложении EM связана с потоком, то один из решениями для управления транзакциями является реализация шаблона Session-Per-Request, который запускает транзакцию при каждом запуске пользовательского запроса и фиксирует и очищает кеш на каждом конце запроса, чтобы предотвратить грязные чтения. Это простой пример.
  • Другой пример - на платформе SOA. Для каждой службы можно также открыть транзакцию в начале и зафиксировать ее в конце с очисткой (в случае, если один и тот же EM используется другой службой, и требуется избегать грязных чтений)
  • Я буду воспроизводить предыдущие два обычных случая - пакетную обработку и обход во всех возможных случаях EM. Поэтому в этом случае запросы будут вынуждены запрашивать из БД, а не из кеша.
  • Вы должны знать, что работаете с кешами L1 и L2, а L1 - это кеш, очищенный EM. Когда вы читаете огромный набор данных (не обязательно) (тогда также требуется очистка в течение периода.

Как вы видите, зависит от случаев, архитектуры и стиля вашей платформы. Непосредственно для вашего метода - это не очень хорошая практика для очистки и очистки кеша на один метод, это анти-шаблонный метод.