Транзакции внутри задач ManagedScheduledExecutorService на TomEE 7.0.0?
контекст
Я хочу запланировать повторяющиеся фоновые задачи, используя ManagedScheduledExecutorService
, Я понимаю Runnable
s /Callable
с помощью Instance
, так что у меня есть возможности инъекции внутри моих задач.
Мое приложение работает TomEE 7.0.0-SNAPSHOT webprofile
,
проблема
Поскольку эти задачи обращаются к базе данных, им нужна транзакция. Однако внутри Runnable
/Callable
транзакция не активна
Пользовательская транзакция
Документация для ManagedScheduledExecutorService гласит, что
Если требуется транзакция, используйте экземпляр javax.transaction.UserTransaction. Экземпляр UserTransaction доступен (...) путем запроса внедрения объекта UserTransaction с помощью аннотации Resource.
Однако введенный
@Resource
private UserTransaction userTransaction;
является null
при вызове задачи.
Бин без гражданства
Другой подход, который я выбрал, заключался в том, чтобы внедрить EJB без состояния в мою задачу, надеясь, что это создаст для меня транзакцию.
Это привело к следующему исключению при запуске:
SEVERE: CDI Beans module deployment failed
java.lang.IllegalStateException: no interface to proxy for ejb StatelessEjb, is this is a MDB maybe you shouldn't use a scope?
at org.apache.openejb.cdi.CdiEjbBean.createEjb(CdiEjbBean.java:252)
at org.apache.openejb.cdi.CdiPlugin.getSessionBeanProxy(CdiPlugin.java:224)
at org.apache.webbeans.container.BeanManagerImpl.getEjbOrJmsProxyReference(BeanManagerImpl.java:951)
at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:777)
at org.apache.webbeans.container.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:651)
at org.apache.webbeans.inject.AbstractInjectable.inject(AbstractInjectable.java:111)
at org.apache.webbeans.inject.InjectableConstructor.createParameters(InjectableConstructor.java:109)
at org.apache.webbeans.inject.InjectableConstructor.doInjection(InjectableConstructor.java:72)
at org.apache.webbeans.portable.InjectionTargetImpl.newInstance(InjectionTargetImpl.java:190)
at org.apache.webbeans.portable.InjectionTargetImpl.produce(InjectionTargetImpl.java:173)
at org.apache.webbeans.portable.AbstractProducer.produce(AbstractProducer.java:172)
at org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:127)
at org.apache.webbeans.component.ManagedBean.create(ManagedBean.java:67)
at org.apache.webbeans.context.DependentContext.getInstance(DependentContext.java:68)
at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:124)
at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:785)
at org.apache.webbeans.inject.instance.InstanceImpl.create(InstanceImpl.java:306)
at org.apache.webbeans.inject.instance.InstanceImpl.get(InstanceImpl.java:123)
(...)
Прецедент
Я создал небольшой тестовый проект на Github. Он содержит две ветви, иллюстрирующие проблемы, упомянутые выше.
Вопросы
- Не должен
@Stateless
EJB работают нормально, так как все экземпляры получены с помощью инъекций? - Почему
@Resource
инъекция дляUserTransaction
потерпеть поражение?
1 ответ
Использование CDI для его получения должно исправить это:
@Inject
private UserTransaction userTransaction;
редактировать: проблема была исправлена для случая @Resource: https://issues.apache.org/jira/browse/TOMEE-1672