Связь между контекстами сеанса cdi - с базой данных, будет ли вызываться надлежащий контекст cdi? - PullRequest
0 голосов
/ 22 марта 2012

У меня проблемы с получением bean-объектов с сессионной областью и EJB-компонентов с отслеживанием состояния для связи между пользовательскими сессиями в одном и том же контейнере java-ee.Методом проб и ошибок я решил использовать базу данных для передачи сообщений между сеансами пользователя.Но теперь у меня есть проблема, как я могу уведомить сеанс пользователя об изменении базы данных? Можно ли запустить поток фонового опроса в контексте сеанса каждого пользователя, чтобы опросить базу данных на предмет изменений?Если это сработает, каков наилучший способ избежать блокировки, но сделать так, чтобы bean-компонент «просыпался» в контексте сеанса своего пользователя?

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

Я пытался использовать Singletons для связи между сеансами пользователя.Но это не работает, потому что как только сообщение, исходящее от пользователя 1, передается бинам пользователя 2, и эти бины запускают событие CDI, событие CDI обрабатывается контекстом сеанса пользователя 1. Это имеет смысл, так как сообщениебыл создан во время сеанса пользователя 1.

Любая помощь будет оценена !!

Ответы [ 2 ]

4 голосов
/ 29 марта 2012

Полагаю, я должен ответить на свой вопрос -

  1. Контексты не распространяются на новые потоки или асинхронные вызовы.Это неопределенное поведение спецификации CDI 1.0, и поэтому контейнеры не обязаны отслеживать, какой контекст создал поток.Если вы создаете поток, а затем запускаете событие CDI, как только поток проснется, это событие CDI не будет иметь активного контекста и выдаст следующую ошибку: org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.RequestScoped или что-то специфическое для области, которую пытался активировать поток. Посмотрите этот билет Glassfish , который на самом деле не является ошибкой, это просто неопределенное поведение.

  2. Поэтому, когда любой поток фонового опроса настроен для проверки, есть лилюбые изменения в данных пользователя, когда поток обнаруживает изменение, с которым он не может связаться (через события CDI) с контекстом сеанса пользователя.В данный момент поток не имеет контекста.Похоже, что этот вопрос остается без ответа для нескольких людей: на форуме jboss и форуме шва .

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

Если бы эксперт CDI по сварке мог исправить меня, если я ошибаюсь, я был бы признателен за это!

0 голосов
/ 30 марта 2012

Я не думаю, что шина событий CDI может использоваться для связи между сеансами пользователя.

Не лучше ли решить эту проблему с помощью JMS-брокера сообщений? Ваше приложение будет масштабироваться намного лучше! Запустите его как отдельный экземпляр или вставьте на сервер приложений. Например, вы можете использовать брокера ActiveMQ.

Опубликуйте уведомление по теме JMS и сделайте так, чтобы пользовательские сеансы подписывались на него. Я еще не использовал JMS-модуль Seam 3 , но похоже, что он способен устранить разрыв между JMS и CDI. Используя Seam JMS, вы можете получать сообщения JMS в каждом сеансе пользователя. Пример в документации объясняет, как для каждого пользователя вы регистрируете прослушиватель JMS в @PostConstruct компонента @SessionScoped.

...