Могу ли я использовать компонент EJB без состояния с CDI для поддержания сеанса пользователя?

#java #jsf-2 #java-ee-6 #cdi #ejb-3.1

#java #jsf-2 #java-ee-6 #cdi #ejb-3.1

Вопрос:

На основе этого сообщения http://www.adam-bien.com/roller/abien/entry/ejb_3_1_killed_the Я использую в своем приложении @Named @Stateless bean для связи с базой данных (ввод здесь EntityManager) и отображения информации на странице jsf. Это отличное упрощение начиная с Java EE 5, но у меня есть один вопрос.

Безопасно ли использовать такие компоненты для поддержания сеанса пользователя (корзина покупок и т.д.)? Я прочитал книгу о ejb 3.0 и знаю, что один и тот же компонент без состояния можно использовать со многими клиентами.

Каков наилучший подход к использованию управляемого компонента со всеми функциями ejb (транзакции, потокобезопасность и т.д.)? Я имею в виду любой другой способ, кроме управляемого компонента интерфейс ejb с реализацией внедрение ejb, как в Java EE 5?

Я использую GlassFish 3.1 WebProfile

Комментарии:

1. Спасибо за ответ, так должен ли я использовать @Named @Stateful или сеанс jsf? Что лучше / облегченнее? сеанс jsf заканчивается, когда пользователь закрывает браузер и сеанс ejb?

2. Или, может быть, внедрить EntityManager в ManagedBean? Безопасно ли это?

3. Сеанс EJB не обязательно заканчивается, когда пользователь закрывает браузер, но у веб-пользователя не будет возможности позже снова подключиться к сеансу EJB. Прокси EJB обычно хранится в области http-сеанса, беседы или просмотра, которые все уничтожаются по окончании основного http-сеанса.

4. > Или, может быть, внедрить EntityManager в ManagedBean? — Возможно, но менее удобно, чем использование EJBs, поскольку в этом случае вам приходится самостоятельно запускать, фиксировать или откатывать транзакции. Управляемый компонент также не должен быть ограничен областью сеанса, если он введен с помощью entity manager. Вам необходимо разделить ваши данные (область действия сеанса) с вашими операциями с БД. Диспетчер объектов в целом не является потокобезопасным.

Ответ №1:

Дополнение к совету duffymo; есть некоторые дополнительные соображения по использованию сеансовых компонентов с сохранением состояния по сравнению с использованием сеанса HTTP.

HTTP-сессия в основном имеет структуру, подобную карте. Он напрямую доступен для всех потоков (запросов), которые являются частью сеанса. Это делает манипулирование несколькими элементами относительно небезопасным действием. Можно выполнить синхронизацию в самом сеансе, но это рискованная операция, которая потенциально может привести к полной блокировке всего вашего приложения. Сеанс HTTP позволяет вам объявлять прослушиватели событий, которые запускаются при любом изменении сеанса http.

Компонент сеанса с отслеживанием состояния, конечно, имеет структуру компонента. У него есть своего рода функция автоматической синхронизации, поскольку одновременно в компоненте может быть активен только поток. С помощью аннотаций вы можете объявить, ожидают ли другие потоки (и если да, то как долго) или немедленно выдать исключение при одновременном доступе.

Там, где обычно существует только один http-сеанс на пользователя, один пользователь может использовать несколько сеансовых компонентов с сохранением состояния одновременно. Особым преимуществом сеансовых компонентов с сохранением состояния является то, что у них есть механизм пассивации своего состояния после некоторого тайм-аута, что может освободить память вашего сервера (за счет дискового пространства, конечно). Сеансовые компоненты с отслеживанием состояния напрямую не имеют прослушивателей событий, которые есть у сеанса http.

Я думаю, что изначально «сессионный» аспект сеансовых компонентов с сохранением состояния заключался в поддержании сеанса с удаленными не веб-клиентами (Swing, другой AS и т.д.). Это очень похоже на то, что http-сеанс был создан для поддержания сеанса с удаленными веб-клиентами. Поскольку не веб-клиент может запрашивать и удерживать несколько прокси-серверов для сеансовых компонентов с отслеживанием состояния, веб-аналогия на самом деле больше похожа на недавно представленную conversation scope .

В случае удаленных веб-клиентов, взаимодействующих с сервером, когда сервер внутренне взаимодействует с сеансовым компонентом с отслеживанием состояния, концепции сильно перекрываются. Удаленный веб-клиент знает только о сеансе http (через JSESSIONID) и ничего о сеансе компонента сеанса с отслеживанием состояния. Таким образом, если http-сеанс был потерян, вы обычно не сможете снова подключить удаленный клиент к определенному сеансовому компоненту с отслеживанием состояния. Таким образом, HTTP-сессия в этом случае всегда лидирует, и вы также можете хранить товары в корзине покупок внутри компонента с одной (http) сессионной областью.

Есть один конкретный случай, когда сеансовые компоненты с сохранением состояния пригодятся для внутренней связи, и это если вам нужны JPA extended persistence context . Это можно использовать, если, например, блокировки объектов должны длиться между запросами (что, возможно, удобно для корзины покупок, если у вас ограниченный запас и вы не хотите сталкивать пользователя с сообщением «нет в наличии», как только он фактически выписывается).

Ответ №2:

Компоненты без состояния не могут поддерживать корзины покупок или сеанс; вот что означает «без состояния».

Вам нужен либо EJB с сохранением состояния, либо сделать это на веб-уровне. Это единственные места, где поддерживается сеанс.