计划进程在Openbravo中同时运行两次(使用Quartz)

我不太确定这是更多的Openbravo问题还是更多的Quartz问题,但我们有一些手动流程通过Openbravo ProcessRequest对象(OB v2.50MP24)按计划运行,但似乎流程正在运行两次,在同一时间。 Openbravo扩展了Quartz平台的日程安排。 我试图通过确保我的进程类扩展此类来自行解决此问题:

 import java.util.List; import org.openbravo.dal.service.OBDal; import org.openbravo.model.ad.ui.ProcessRequest; import org.openbravo.scheduling.ProcessBundle; import org.openbravo.service.db.DalBaseProcess; public abstract class RBDDalProcess extends DalBaseProcess { @Override protected void doExecute(ProcessBundle bundle) throws Exception { org.quartz.Scheduler sched = org.openbravo.scheduling.OBScheduler .getInstance().getScheduler(); int runCount = 0; synchronized (sched) { List currentlyExecutingJobs = (List) sched .getCurrentlyExecutingJobs(); for (org.quartz.JobExecutionContext jec : currentlyExecutingJobs) { ProcessRequest processRequest = OBDal.getInstance().get( ProcessRequest.class, jec.getJobDetail().getName()); if (processRequest == null) continue; String processClass = processRequest.getProcess() .getJavaClassName(); if (bundle.getProcessClass().getCanonicalName() .equals(processClass)) { runCount++; } } } if (runCount > 1) { System.out.println("Process " + bundle.getProcessClass().getSimpleName() + " is already running. Cancelling."); return; } doRun(bundle); } protected abstract void doRun(ProcessBundle bundle); } 

当我通过请求进程同时立即运行两次测试时,这工作正常。 其中一人取消了。 但是,它不适用于计划的进程。 我有Sop设置为进程开始时记录,并查看日志显示输出的每一行两次,每一行一个接一个。

我有一种潜在的怀疑,因为这些进程要么在两个完全不同的线程中运行,而这些线程不了解彼此的进程,但是,我不确定如何validation我的怀疑,或者,如果我是正确的,那么做到这一点。 我已经validation了数据库中只存储了每个ProcessRequest对象的一个​​实例。

有没有其他人经历过这个,知道为什么他们可能会跑两次,或者知道我能做些什么来防止它们同时运行?

双重作业执行的最常见原因如下:

编辑:

  • 您的应用程序部署在集群环境中,并且尚未将Quartz配置为在集群环境中运行。
  • 您的应用程序不止一次部署。 在许多情况下,应用程序部署两次,特别是在Tomcat服务器中。 因此,QuartzInitializerListener被调用两次,Jobs被执行两次。 如果您使用Tomcat服务器并且在server.xml中显式定义上下文,则应关闭自动应用程序部署或指定deployIgnore。 autoDeploy设置为true且server.xml中存在context元素,因此应用程序的两次部署。 将autoDeploy设置为false或从server.xml中删除context元素。
  • 您的应用程序已重新部署,无需安排当前流程。

我希望这可以帮助你。

Quartz使用线程池来执行作业。 因此,正如您所怀疑的那样, RBDDalProcess可能在单独的线程中具有单独的实例,并且计数器检查将失败。

您可以做的一件事是列出在Scheduler中注册的作业(您可以使用OB API获取Scheduler: OBScheduler.getScheduler() ):

 // enumerate each job group for(String group: sched.getJobGroupNames()) { // enumerate each job in group for(JobKey jobKey : sched.getJobKeys(groupEquals(group))) { System.out.println("Found job identified by: " + jobKey); } } 

如果您看到两次添加相同的作业,请查看org.quartz.spi.JobFactory和org.quartz.Scheduler.setJobFactory方法以控制作业实例化。

还要确保在Openbravo的“报告和处理”表中只有一个用于此过程的条目。

我在Openbravo 3.0中使用过DalBaseProcess ,我无法确认你所描述的这种行为。 考虑到这一点,检查Openbravov2.50MP24和Quartz报告的错误或在Openbravo Forge论坛中发布一个问题可能是一个好主意。