2017-11-15 6 views
0

私は並列で動作するはずのactivitiに2つのサービスタスクを実装しようとしています。以下に書かれたコードは無作為に(そして面白く)うまくいく。私はそれがときどき "最初"(または "秒")だけを印刷するか、2つの "最初の" 1秒 "などを印刷することを意味します。これらのサービスを、現在サービスの数を無条件でランニング?Activiti並列サービスのタスク

PS:プロセス定義からactiviti:async = "true"を削除したとき、 "first"または "second"のみが表示されました。私は私が必要と推測

:)そのプロセス定義:

<?xml version='1.0' encoding='UTF-8'?> 
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 
    xmlns:activiti="http://activiti.org/bpmn" targetNamespace="Examples"> 

<process id='testparallelact' name="Developer Hiring" isExecutable="true" activiti:exclusive="false" activiti:async="true"> 

    <startEvent id="theStart" /> 
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" /> 

<parallelGateway id="fork" activiti:async="true" /> 
<sequenceFlow sourceRef="fork" targetRef="receivePayment" /> 
<sequenceFlow sourceRef="fork" targetRef="shipOrder" /> 


<serviceTask id="receivePayment" name="Receive Payment" activiti:async="true" activiti:exclusive="false" 
      activiti:expression="${serviceConnections.runThis2('First')}"/> 

<sequenceFlow sourceRef="receivePayment" targetRef="join" /> 


<serviceTask id="shipOrder" name="Ship Order" activiti:async="true" activiti:exclusive="false" 
      activiti:expression="${serviceConnections.runThis2('Second')}"/> 

<sequenceFlow sourceRef="shipOrder" targetRef="join" /> 

<parallelGateway id="join" /> 
<sequenceFlow sourceRef="join" targetRef="theEnd" /> 
<endEvent id="theEnd" /> 
</process> 
</definitions> 

runThis2:

public void runThis2(String test1) throws InterruptedException { 

     while(true) 
     { 
      Thread.sleep(1000); 
      System.out.println(test1); 

     } 

    } 

答えて

0

それはジョブがActivitiエンジン内で実行されているかを理解することが重要です。 次フォーラムのスレッドには、それを記述するかなり良い仕事をしていません:

https://community.alfresco.com/thread/221453-multiinstance-wont-run-task-in-parallel

元Activitiの建築家の一人からキーの抜粋:

「並列ゲートウェイとマルチインスタンスの構築物は実行することができますたとえば、 スクリプトタスクの場合、これらのタスクは基本的にシリアルで実行されます。 falseを排他的に設定すると、この動作が変更されます(デフォルトの は真です)。ジョブ実行者は、 という利用可能なすべてのジョブを実行し、連続して実行しません。だから、それをfalseに 真と排他的に非同期(async)を設定するために試してみる。」

を今、排他的な非同期を設定しないで、何が効果的に行っているが作成された 『割り当てることによって、プロセス内で待機状態』

Job Schedulerによって並列実行されるジョブと実行されるジョブの数は、Job Executorの構成によって完全に制御されるようになりました(スレッドプールのサイズ、タイムアウト、数値ジョブブロックのサイズはすべて設定可能です)。

これはまったく元のものではありませんつまり、ジョブキューのサイズ、1回のスイープで実行されるジョブの数、およびサービスタスクがいつ実行されるかについての各ジョブの継続時間に依存します。意味、彼らは並行して実行されるかもしれませんし、連続して実行されるかもしれません。同様に、ジョブ実行者が何をいつ実行するのかを判断するために、一度やり直してから順序を制御することはできません。

これはあなたの要件を満たしていると仮定します。

問題がもう1つあります(実際は、「排他的」フラグが最初に導入された理由です)。サービスタスクが完了すると、実行コンテキストはデータベースのプロセスインスタンスレコードと履歴レコードにコミットされます。 Activitiは、パフォーマンス目的でレコードに「オプティミスティックロック」を使用します。プロセスの分岐が時間内に比較的近い場合、DB更新に関するオプティミスティックロックの例外が発生する可能性があります(実際にはそうである可能性が高いです)。

09:59:52,432 [flowable-async- job-executor-thread-2]エラーorg.flowable.job.service.impl.asyncexecutor.DefaultAsyncRunnableExecutionExceptionHandler - ジョブ12575が失敗しました org.flowable.engine.common.api.FlowableOptimisticLockingException:ProcessInstance [12567]が別のトランザクションによって同時に更新されました

上記の例は、Flowableのものですが、Activitiと本質的に同じコードベースですあなたがログに表示されるものの現在の6)。これにより、サービスタスクに失敗とタグ付けされ、が再試行になります。これは、SOR(System of Record)やその他のレガシーシステムへの外部呼び出しを行う場合に問題になります(フライト実際に予約されましたが、失敗したと認識されたために予約しておくよう呼びかけました。

良いデザインとベストプラクティスの使用で解決できるすべての楽しいものとすべてのもの。

これは、何が起こっているのか理解するのに役立ちます。

greg @ BP3

関連する問題