Jakarta ee JavaEE7:调用EJB方法+;交易自";非托管;上下文 请考虑以下情况:
1) 一个单例SchedulerService,除其他功能外,它管理/创建一组Jakarta ee JavaEE7:调用EJB方法+;交易自";非托管;上下文 请考虑以下情况:,jakarta-ee,managed-bean,java-ee-7,Jakarta Ee,Managed Bean,Java Ee 7,1) 一个单例SchedulerService,除其他功能外,它管理/创建一组JobQueue @Startup @Singleton public class SchedulerService { @Inject private Instance<JobQueue> jobQueueInstance; ... public JobQueue addQueue(String name) { JobQueue q = job
JobQueue
@Startup
@Singleton
public class SchedulerService
{
@Inject
private Instance<JobQueue> jobQueueInstance;
...
public JobQueue addQueue(String name)
{
JobQueue q = jobQueueInstance.get();
....
return q;
}
}
一切正常,entityManager被正确地@Injected,当从其他托管bean调用addJob()
和deleteJob()
时,实体被正确地持久化/删除
现在,对于实际的作业执行,我使用的是Cron4j,它不支持CDI。
它启动新线程并在该线程中运行实际作业。
当作业结束时,它通过tasksuccessed
/taskFailed
方法通知我的作业队列(侦听作业终止事件的人)
由于这些taskseceded
/taskFailed
方法是从作业线程(不是“容器管理的”)调用的,因此我可以理解得到以下异常:
4:46:27,032 ERROR [cob.scheduler.service.JobQueue] (cron4j::scheduler[DEFAULT]::task[442]) Job xxx failed: javax.persistence.TransactionRequiredException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)
at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:869) [wildfly-jpa-9.0.0.Alpha1.jar:9.0.0.Alpha1]
at org.jboss.as.jpa.container.AbstractEntityManager.merge(AbstractEntityManager.java:567) [wildfly-jpa-9.0.0.Alpha1.jar:9.0.0.Alpha1]
at cob.scheduler.service.JobQueue.deleteJob(JobQueue.java:287) [classes:]
at cob.scheduler.service.JobQueue.deleteAndAdvance(JobQueue.java:241) [classes:]
at cob.scheduler.service.JobQueue.taskSucceeded(JobQueue.java:226) [classes:]
at it.sauronsoftware.cron4j.Scheduler.notifyTaskSucceeded(Scheduler.java:724) [classes:]
at it.sauronsoftware.cron4j.TaskExecutor$Runner.run(TaskExecutor.java:500) [classes:]
at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_45]
我想知道什么是继续进行的好方法。基本上,我需要以某种方式“回到EE容器”,即从EE领域之外调用容器管理的方法
我已经读过有关ManagedExecutorService
的内容,但我不确定这是否适用或如何使用它
我还尝试@注入私有JobQueue self
并调用self.deleteJob()
,而不仅仅是this.deleteJob()
,但这会在部署时生成以下异常:
org.jboss.weld.exceptions.DeploymentException: WELD-001443: Pseudo scoped bean has circular dependencies. Dependency path:
- Managed Bean [class cob.scheduler.service.JobQueue] with qualifiers [@Any @Default],
- [BackedAnnotatedField] @Inject private cob.scheduler.service.JobQueue.self,
- Managed Bean [class cob.scheduler.service.JobQueue] with qualifiers [@Any @Default]
at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:904)
at org.jboss.weld.bootstrap.Validator.validatePseudoScopedInjectionPoint(Validator.java:946)
at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:913)
at org.jboss.weld.bootstrap.Validator.validatePseudoScopedBean(Validator.java:890)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:148)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:165)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:529)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_45]
... 3 more
注意:除了“资源本地”事务管理,我的一切都正常工作。我想把它转换成JTA很容易,但唉
任何指点都将不胜感激。结果证明解决方案并不那么难。我们每天都在学习。是的
SchedulerService
注入JobQueue
。这就产生了一种循环依赖性,但很好SchedulerService
中,创建一个代理方法deleteJob(JobQueue jq,Job j)
。所有这些都是调用jq.deleteJob(j)
schedulerService.deleteJob(this,j)
,而不是this.deleteJob(j)
。通过检查@inspected代理,JavaEE再次发挥作用,为我们和所有其他奇妙的魔力创造了交易您可以避免使用cron4J,在一个ejb中的方法上使用
@Schedule
,也可以使用编程计时器以编程方式创建计划任务。在任何一种情况下,他们都将使用CMT,您不必跳过所有这些障碍。@NBW感谢我知道@Schedule
和其他替代方案,但我需要最大的灵活性/可配置性来模拟一些遗留行为。
org.jboss.weld.exceptions.DeploymentException: WELD-001443: Pseudo scoped bean has circular dependencies. Dependency path:
- Managed Bean [class cob.scheduler.service.JobQueue] with qualifiers [@Any @Default],
- [BackedAnnotatedField] @Inject private cob.scheduler.service.JobQueue.self,
- Managed Bean [class cob.scheduler.service.JobQueue] with qualifiers [@Any @Default]
at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:904)
at org.jboss.weld.bootstrap.Validator.validatePseudoScopedInjectionPoint(Validator.java:946)
at org.jboss.weld.bootstrap.Validator.reallyValidatePseudoScopedBean(Validator.java:913)
at org.jboss.weld.bootstrap.Validator.validatePseudoScopedBean(Validator.java:890)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:148)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:165)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:529)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_45]
... 3 more