Компонент регистрации RequestScoped с асинхронными вызовами

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

У меня есть bean-компонент, который вызывает два метода @Asynchronous. Эти два метода @Asynchronous вызывают базу данных и перехватываются.

Однако, когда компонент регистрации регистрируется, кажется, что база данных заняла 0 мс, что не может быть правильным. Когда я использую этот компонент ведения журнала и все перехватчики без вызовов @Asynchronous, все работает нормально.

Я использую стеклянную рыбу 3.1.2.2. Документ http://glassfish.java.net/nonav/docs/v3/api/javax/enterprise/context/RequestScoped.html говорит: «Контекст запроса уничтожается: после завершения уведомления асинхронного наблюдателя». Означает ли это, что мой экземпляр компонента ведения журнала в @Asynchronous метод уничтожается, когда метод завершается? Что я могу использовать для достижения своей цели?


person user1608137    schedule 13.03.2013    source источник


Ответы (1)


Есть несколько слоев:

  1. Прокси-сервер CDI, который запускает перехватчики CDI, а затем вызывает EJB.
  2. Прокси-сервер EJB, который планирует асинхронную работу и немедленно возвращает результат.
  3. Перехватчики EJB, работающие в асинхронном потоке.

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

person Brett Kail    schedule 16.03.2013
comment
Я думаю, что использую перехватчики EJB. У меня есть @Interceptors({Class.class}, аннотированный на уровне класса, и импорт выглядит так: import javax.interceptor.AroundInvoke; import javax.interceptor.InvocationContext; - person user1608137; 18.03.2013
comment
Я был уверен, что это было в спецификации EJB, но сейчас не могу найти. Возможно, есть несоответствие между реализациями. Я тестировал на WebSphere Application Server, и он вызывает перехватчики в асинхронном потоке. Возможно, попробуйте напечатать Thread.currentThread().toString/.getId/.getName из перехватчика и асинхронного метода, чтобы подтвердить поведение Glassfish? - person Brett Kail; 18.03.2013
comment
Перехватчики выполняются правильно для асинхронных методов. Они вызывают LoggingBean после invocation.proceed() и добавляют время, необходимое для общения с базой данных, в loggingbean... например. вызов.процедура(); loggingbean.addDBTime (System.currentMillis () — запуск); все это работает правильно, но когда последний перехватчик (на уровне трикотажа) вызывает метод loggingbean.log(), время базы данных равно 0. Я проверил, что перехватчик базы данных регистрирует время, отличное от 0. - person user1608137; 19.03.2013
comment
Какое значение передается в addDBTime? Что такое логгинбин? Как он был создан/получен? Вызываются ли методы addDBTime и log для одного и того же экземпляра loggingbean? - person Brett Kail; 19.03.2013
comment
я передаю длинные (примитивные) методу addDBTime. loggingbean — это класс с областью запроса, который имеет методы addDbTime (long l), setURI (String s), setJerseyTime (long l) и setEJBTime (long l). loggingbean @Injected в перехватчики, которые фиксируют, сколько времени занял каждый процесс. Я не знаю, вызываются ли addDBTime и log в одном и том же экземпляре. Должен ли я просто println (LoggingBean), чтобы увидеть место в памяти? - person user1608137; 19.03.2013
comment
Назначьте каждому компоненту ведения журнала идентификатор (например, статический AtomicInteger) и добавьте ведение журнала к каждому из методов. Я предполагаю, что область запроса теряется при переключении потоков для асинхронного вызова. - person Brett Kail; 19.03.2013