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

Безстоящий сеанс Beans против сеанса Singleton Beans

Java EE 6 Tutorial говорит:

Чтобы повысить производительность, вы можете выбрать сеанс без состояния bean, если он имеет какие-либо из этих признаков:

  • Состояние bean s не имеет данных для конкретного клиента.
  • В одном вызове метода bean выполняет общую задачу для всех клиентов. Например, вы можете использовать сеанс без состояния bean, чтобы отправить электронное письмо, подтверждающее онлайн-заказ.
  • bean реализует веб-службу.

Singleton session beans применимы в следующих случаях:

  • Состояние должно быть общим для приложения.
  • Одному предприятию bean необходимо одновременное обращение к нескольким потокам.
  • Приложению необходимо выполнить bean для выполнения задач при запуске и завершении работы приложения.
  • bean реализует веб-службу.

Но что использовать, если:

  • никакое состояние не должно использоваться совместно приложением
  • к одному предприятию bean можно было обращаться несколькими потоками одновременно
  • Никаких задач при запуске или дроблении не требуется.

Скажем, например, у меня есть служба входа в систему со следующим интерфейсом:

public interface LoginService {
  boolean authenticate(String user, String password);
}

Должен ли он быть аннотирован с помощью @Singleton или @Stateless? Каковы преимущества того и другого? Что делать, если в LoginService необходимо ввести EntityManager (который будет использоваться одновременно)?

Дополнение: Я думаю о Java EE-аналоге службы Spring beans, которые являются безстоящими синглтонами. Если я правильно понимаю, что Java EE-экземпляр - это @Stateless session beans и @Singleton beans, используются для настройки приложения при запуске или очистке при завершении работы или для хранения объектов широкого применения. Правильно ли это?

4b9b3361

Ответ 1

Я бы пошел на Stateless - сервер может генерировать много экземпляров bean и обрабатывать входящие запросы параллельно.

Синглтон звучит как потенциальное узкое место - значение по умолчанию @Lock по умолчанию @Lock (WRITE), но может быть изменено на @Lock (READ) для bean или отдельных методов.

Ответ 2

в соответствии со спецификацией ejb 3.1, стр. 110, глава 4.8.5 "Singleton Concurrency":

Законно хранить объекты Java EE, которые не поддерживают параллельный доступ (например, Entity Managers, Sessionful Session Bean ссылки) в состоянии экземпляра Singleton Bean. Однако разработчик Bean несет ответственность за обеспечение доступа к таким объектам не более чем по одному потоку за раз.

и, кроме того, в соответствии с документацией hibernate entitymanager

EntityManager - недорогой, не-потоковый объект, который должен использоваться один раз, для одного бизнес-процесса, отдельной единицы работы и затем отбрасываться.

Для меня это означает, что вы никогда не должны вводить EntityManager в одноэлементный EJB. Я бы использовал одноэлементный EJB в качестве замены для EAS файла без состояния, только если ВСЕ, что мне нужно реализовать в этом классе, поддерживает concurrency без необходимости делать дополнительную блокировку/синхронизацию. Поскольку вы или другие программисты могут рано или поздно потерять эту проблему из своего внимания, я лично предпочитаю не использовать одиночные EJB, кроме проблем или функций, связанных с запуском, которые могут быть реализованы как автономные блоки - независимо от других beans. В этом смысле, кажется, не рекомендуется вводить, например, EJB без гражданства в синглтоны. Это вызывает вопрос о времени, когда контейнер фактически выполняет инъекцию SLSB в Singleton? В соответствии с EJB 3.1 Spec, глава 4.8, инъекция зависимостей выполняется до того, как экземпляр singleton Bean может быть доступен клиентам. Таким образом, синглтон, очевидно, будет придерживаться одного и того же экземпляра SLSB, который, похоже, будет неявным образом, но, похоже, для этого не существует никакой гарантии. По крайней мере, я не мог найти ничего в спецификациях, поэтому поведение может быть непредсказуемым или в лучшем случае конкретным контейнером, что не то, что большинство людей захочет.

Таким образом, я бы только вводил Singletons в Singletons или Singletons в SLSB, но не наоборот. В случае инъекции Singleton в Singleton Spec предлагает вам возможность определять зависимости между синглонами, чтобы контейнер мог инициализировать их в правильном порядке (см. Спецификацию ejb 3.1, глава 4.8.1, касающаяся @DependsOn).

Ответ 3

@Stateless позволит вам иметь несколько копий, готовых для обработки в JVM (насколько позволяет размер памяти и пула), где - как @Singleton - только одна копия в JVM, даже если один может поддерживать несколько параллельные потоки, выполняющиеся против него.

С точки зрения производительности @Singleton было бы лучше, при условии, что ресурсы, которые он использует, позволяют долго работать. Однако в распределенной среде иногда возникают плохие вещи, например, база данных или сетевые ссылки могут выйти из строя.

С @Stateless bean доступ более короткий. Кроме того, если возникнет сбой, он просто восстанет и попытается установить новое соединение с ресурсом. Если что-то происходит в одноэлементном режиме, то это синглтон, чтобы обработать его, не требуя перезапуска приложения, потому что @PostConstruct вызывается только один раз на JVM.

Я бы предпочел немного отказоустойчивости и производительности для большинства ситуаций, особенно в системах, в которых я не контролирую.

Ответ 4

Я думаю, что использование Singleton в concurrency не будет хуже, чем SLSB Pool, это может быть даже лучше. Единственная проблема заключается в том, что если вы хотите поделиться чем-то между потоками, вам нужно заблокировать его, и это может быть большой проблемой производительности. Таким образом, в этом случае SLSB Pool работает намного лучше, потому что это не 100% singleton, есть больше случаев, один заперт, другой появляется. В любом случае, если блокировка включена в разделение ресурсов всеми SLSB, пул не поможет ни тем, ни другим.

Короче говоря, я думаю, что singleton лучше, чем SLSB Pool, вы должны использовать его, если сможете. Это также область по умолчанию для Spring Beans.

Я не эксперт по JavaEE, это просто мое чувство, пожалуйста, поправьте меня, если я ошибаюсь.

Ответ 5

Думаю, вы должны использовать Singleton session bean. Поскольку служба входа в систему должна быть глобальной службой, и ей не нужно сохранять какое-либо состояние для конкретного пользователя или вызова.

Ответ 6

Если вы уверены, что не разделяете состояние между потоками, то Singleton будет в порядке, и в этом случае вы также должны аннотировать класс с помощью @ConcurrencyManagement( ConcurrencyManagementType.BEAN ), который позволит одновременно запускать несколько потоков.

Ответ 7

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

Ответ 8

Imho я бы ответил так:

"никакое состояние не должно быть общим для приложения" приводит меня к безстоящему bean из-за предложения "Чтобы повысить производительность, вы можете выбрать сеанс без состояния bean...".

Учитывая, что "одно предприятие bean может быть доступно несколькими потоками одновременно", вам придется использовать singleton. Если я правильно понял, то при правильном использовании даже без возможности доступа к безстоящему bean доступу.

"Никаких задач при запуске или сбое необходимо выполнить" для меня не имеет значения. Если для правильной настройки bean необходимо выполнить задачи, то они должны быть вызваны методом @PostActivate.

Я логически закончил бы ваш вопрос, что использовать для @Singleton, так как вы просили о параллельном доступе. Конечно, вам придется вручную контролировать sinychronisation доступа на любых дополнительных ресурсах (которые не являются EJB).