请考虑以下情况:
1)一个Singleton SchedulerService,其中包括管理/创建一堆JobQueue
s
@Startup
@Singleton
public class SchedulerService
{
@Inject
private Instance<JobQueue> jobQueueInstance;
...
public JobQueue addQueue(String name)
{
JobQueue q = jobQueueInstance.get();
....
return q;
}
}
2)可能有几个JobQueue
人管理/启动/跟进他们的正在运行/待处理的工作:
public class JobQueue implements SchedulerListener
{
@PersistenceContext(unitName = "...")
private EntityManager entityManager;
public void addJob(Job newJob)
{
.... entityManager.persist(newJob); ....
newJob.addSchedulerListener(this);
}
...
public void deleteJob(Job j)
{
.... entityManager.delete(j); ....
}
// part of SchedulerListener, invoked from Job's Thread
@Override
public void taskSucceeded(Job job)
{
deleteJob(job);
}
// part of SchedulerListener, invoked from Job's Thread
@Override
public void taskFailed(Job job)
{
deleteJob(job);
}
}
一切正常,entityManager正确@Injected,从其他托管bean调用addJob()
和deleteJob()
时,实体被正确保留/删除。
现在,对于实际的Job执行,我使用的是Cron4j,它不支持CDI。
它启动新的Threads并在该Thread中运行实际的Job。
当作业结束时,它会通过taskSucceeded
/ taskFailed
方法通知我的JobQueue(谁听取了Job终止事件)。
因为这些taskSucceeded
/ taskFailed
方法是从作业线程(不是&#34;容器管理&#34;)中调用的,所以我理解为得到以下例外:
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容器&#34;,即从EE领域外部调用容器管理方法。
我已阅读ManagedExecutorService
,但我不确定这是否适用或如何使用。
此外,我尝试@Inject private 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
注意:我已经完成了所有工作但是使用了#34;资源本地&#34;交易管理。我认为很容易将其转换为JTA,但唉。
任何指针都会受到赞赏。
答案 0 :(得分:1)
原来解决方案并不那么难。我们每天都在学习。 Yey!
SchedulerService
注入JobQueue
。这造成了圆形的依赖性,但是很好。SchedulerService
中,制作代理方法deleteJob(JobQueue jq, Job j)
。所有这一切都是调用jq.deleteJob(j)
schedulerService.deleteJob(this, j)
而不是this.deleteJob(j)
。通过遍历@Injected代理,Java EE再次启动,为我们和所有其他奇妙的魔法创建交易。