8

これがOpenbravoの問題なのか、Quartzの問題なのかはよくわかりませんが、OpenbravoProcessRequestオブジェクト(OB v2.50MP24)を介してスケジュールに従って実行される手動プロセスがいくつかありますが、プロセスは2回実行されているようです。 、まったく同時に。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<org.quartz.JobExecutionContext> currentlyExecutingJobs = (List<org.quartz.JobExecutionContext>) 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);

}

これは、プロセスをすぐに2回同時に実行するように要求してテストしたときに、正常に機能しました。それらの1つはキャンセルされました。ただし、スケジュールされたプロセスでは機能していません。プロセスの開始時にログに記録するようにSopを設定しました。ログを見ると、出力の各行が2回、各行が次々に表示されます。

プロセスがお互いのプロセスを知らない2つの完全に異なるスレッドで実行されているためだとこっそり疑っていますが、疑惑を確認する方法や、正しい場合はどうすればよいかわかりません。それについてしなさい。ProcessRequestデータベースに格納されている各オブジェクトのインスタンスが1つしかないことをすでに確認しました。

他の誰かがこれを経験したことがありますか、なぜ彼らが2回実行されているのか、またはそれらが同時に実行されないようにするために私ができることを知っていますか?

4

2 に答える 2

6

二重のジョブ実行の最も一般的な理由は次のとおりです。

編集:

  • アプリケーションはクラスター化された環境にデプロイされており、クラスター環境で実行するように Quartz を構成していません。
  • アプリケーションが複数回デプロイされています。特に Tomcat サーバーでは、アプリケーションが 2 回デプロイされることがよくあります。結果として、QuartzInitializerListener が 2 回呼び出され、ジョブが 2 回実行されます。Tomcat サーバーを使用していて、server.xml でコンテキストを明示的に定義している場合は、アプリケーションの自動展開をオフにするか、deployIgnore を指定する必要があります。true に設定された autoDeploy と server.xml 内のコンテキスト要素の存在の両方により、結果としてアプリケーションが 2 回デプロイされます。autoDeploy を false に設定するか、server.xml からコンテキスト要素を削除してください。
  • 現在のプロセスのスケジュールを解除せずに、アプリケーションが再デプロイされました。

これがお役に立てば幸いです。

于 2012-08-21T11:32:51.830 に答える
2

Quartzは、ジョブの実行にスレッドプールを使用します。したがって、ご想像のとおり、RBDDalProcessはおそらく別のスレッドに別のインスタンスがあり、カウンターチェックは失敗します。

実行できることの1つは、スケジューラーに登録されているジョブをリストすることです(OB APIを使用してスケジューラーを取得するには次のようにします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);
    }
}

同じジョブが2回追加されている場合は、ジョブのインスタンス化を制御するためのorg.quartz.spi.JobFactoryメソッドとorg.quartz.Scheduler.setJobFactoryメソッドを確認してください。

また、Openbravoの「レポートとプロセス」テーブルにこのプロセスのエントリが1つしかないことを確認してください。

私はDalBaseProcessOpenbravo3.0で使用しましたが、あなたが説明しているこの動作を確認できません。これを念頭に置いて、Openbravov2.50MP24とQuartzについて報告されたバグをチェックアウトするか、OpenbravoForgeフォーラムに問題のスレッドを投稿することをお勧めします。

于 2012-08-21T12:06:55.453 に答える