EJB 3.1 Singleton + JPA + JSF нужны рекомендации по дизайну - PullRequest
5 голосов
/ 15 августа 2011

Дано: простое веб-приложение JSF (без шва), имеющее JSF-бины, вызывающие несколько EJB-компонентов, которые в свою очередь загружают и сохраняют сущности JPA. Я хочу использовать @Singleton аннотацию для ejb и inject EntityManager вместо EntityManagerFactory:

@Singleton
public class MyEJB {
  @PersistenceContext(unitName = PERSISTENCE_UNIT_NAME)
  protected EntityManager em; // not EntityManagerFactory
}

Спецификация говорит, что @Singleton является поточно-ориентированным, поддерживает параллелизм и атрибуты транзакции, что (из моего pov) делает его безопасным для вызова из bean-компонентов JSF. Я ожидаю также повышения производительности из-за того, что EntityManager не воссоздается при каждом вызове, и его внутренние возможности кэширования.

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

  • Что произойдет, если один синглтон обновит экземпляр JPA и как они изменения заселены в другие синглтоны?
  • Поскольку я не могу закрыть менеджер сущностей, нужно ли мне его сбрасывать каждое обновление сущности?
  • Было бы лучше, если бы эти несколько синглетонов имели одну и ту же сущность менеджер
  • Я видел только несколько примеров такого дизайна. Зачем? Есть ли серьезные недостатки?

Заранее большое спасибо!

Ответы [ 2 ]

5 голосов
/ 15 августа 2011

Я ожидаю также повышения производительности из-за того, что EntityManager не воссоздается для каждого вызова и его внутренние возможности кэширования.

Вы можете сэкономить некоторую память с помощью синглетонов, но использование ее повсеместно в вашем приложении может сделать ее на самом деле медленнее, поскольку, поскольку имеется только один EJB-компонент для обслуживания всех одновременных запросов различных пользователей вашего приложения, контейнер блокирует доступ к EJB-компоненту. и когда он занят обслуживанием запроса, он не может обслуживать другой запрос. Однако это можно в некоторой степени облегчить, используя типы блокировки (т. Е. @Lock(WRITE) и @Lock(READ)).

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

Что произойдет, если один синглтон обновит экземпляр JPA и как эти изменения будут перенесены в другие синглтоны?

Не должно отличаться от поведения не-одиночных EJB-компонентов.

Поскольку я не могу закрыть менеджер сущностей, нужно ли его сбрасывать при каждом обновлении сущности?

Если вы используете CMT, нет. В конце каждой транзакции все будет сброшено автоматически.

Было бы лучше, если бы эти несколько синглетонов имели одного и того же менеджера сущностей?

Для меня это выглядит преждевременной оптимизацией. Просто позвольте контейнеру впрыскивать EM для вас.

Я видел только несколько примеров такого дизайна. Зачем? Есть ли серьезные недостатки?

Уже объяснил.

0 голосов
/ 24 июля 2014

Я хочу упомянуть одну вещь, касающуюся изменения LockType синглтон-EJB-компонентов.Хотя в целом это звучит как хорошая идея, вы должны помнить, что такие ресурсы, как EntityManger, НЕ являются поточно-ориентированными, поэтому необходимо обеспечить соответствующий контроль одновременного доступа.С помощью @Lock (WRITE) вы можете аннотировать методы, которые обращаются к не поточно-ориентированным ресурсам, но если почти все методы интерфейса вашего Singleton EJB обращаются к таким ресурсам, у вас будет почти такая же ситуация, как и с полностью заблокированной записью.Альтернативой является использование Bean Concurrency Management с точной синхронизацией вручную, но это также сомнительное решение.

Из-за этого в целом я предпочитаю EJB без сохранения состояния, а не Singleton, и использую последние в особых случаях.

...