第6章 プロセスモデリング


6.1. 役に立つ定義

このセクションでは、このガイドの他の章で使用されている用語について説明します。
プロセス定義 は、ビジネスプロセスの正式な仕様を表すものであり、有向グラフ に基づいています。グラフは、ノードと遷移で構成されます。グラフ内のすべてのノードは、特定のタイプのノードです。ノードタイプはランタイムの動作を定義します。プロセス定義には、開始状態が 1 つしかありません。
トークン は、実行の 1 つのパスです。トークンは、グラフ内のノードへのポインターを保持するランタイムの概念です。
プロセスインスタンス は、プロセス定義の 1 つの実行です。プロセスインスタンスが作成されると、実行のメインパスに対してトークンが生成されます。このトークンはプロセスインスタンスの ルートトークン と呼ばれ、プロセス定義の 開始状態 に配置されます。
シグナルは、トークンにグラフ実行を続行するように指示します。トークンは名前のないシグナルを受信すると、デフォルトの 退出遷移 を介して現在のノードから退出します。シグナルで transition-name が指定されている場合、トークンは指定された遷移を介してそのノードから退出します。プロセスインスタンスに与えられたシグナルは、ルートトークンに委譲されます。
トークンがノードに進入すると、ノードが実行されます。ノード自体は、グラフ実行を継続させる役割があります。グラフ実行の継続は、トークンをノードから退出させることで実現されます。各タイプのノードは、グラフ実行の継続のために異なる動作を実装できます。実行を渡さないノードは 状態 として動作します。
アクション は、プロセス実行中にイベントで実行される Java コードの一部です。グラフ は、ソフトウェア要件の伝達において重要な手段ですが、作成中のソフトウェアの 1 つのビュー (プロジェクション) にすぎません。多くの技術的な詳細は、そこには表示されません。アクションは、グラフィカルな表現以外の技術的な詳細を追加するために使用されるメカニズムです。グラフを配置したら、アクションで装飾することができます。主な イベントタイプ は、ノード進入ノード退出遷移取得 です。
これらの定義を理解したら、次に進み、プロセスモデリングの仕組みを確認してください。

6.2. プロセスグラフ

プロセス定義は、ノードと遷移で構成されるグラフです。この情報は XML で表現され、processdefinition.xml というファイルにあります。各ノードには タイプ が必要です (状態決定フォーク、および ジョイン など)。 各ノードには、一連の 退出遷移 があります。ノードから退出する遷移には、それらを区別するために名前を付けることができます。たとえば、次の図は、オークションプロセスのプロセスグラフを示しています。

図6.1 オークションプロセスのグラフ

オークションプロセスのグラフ
以下は、同じオークションプロセスを XML で表したプロセスグラフです。
<process-definition>

  <start-state>
    <transition to="auction" />
  </start-state>
  
  <state name="auction">
    <transition name="auction ends" to="salefork" />
    <transition name="cancel" to="end" />
  </state>
  
  <fork name="salefork">
    <transition name="shipping" to="send item" />
    <transition name="billing" to="receive money" />
  </fork>
  
  <state name="send item">
    <transition to="receive item" />
  </state>

  <state name="receive item">
    <transition to="salejoin" />
  </state>
  
  <state name="receive money">
    <transition to="send money" />
  </state>

  <state name="send money">
    <transition to="salejoin" />
  </state>
  
  <join name="salejoin">
    <transition to="end" />
  </join>
  
  <end-state name="end" />
  
</process-definition>

6.3. ノード

プロセスグラフは、ノードと遷移で構成されます。各ノードは特定のタイプのノードです。ノードタイプにより、ランタイム時にノードに実行が到達したときの動作が決定されます。Business Process Manager は、使用する一連のノードタイプを提供します。または、カスタムコードを記述して、特定のノードの動作を実装することもできます。

6.3.1. ノードの役割

各ノードには 2 つの主な役割があります。まず、ノードはプレーンな Java コードを実行できます。このコードは、通常はノードの機能に関連するものです。2 番目の役割は、プロセスの実行を渡すことです。
ノードは、プロセスの実行を渡そうとするときに、次の選択肢に直面することがあります。ノードは最も適切なコースに従います。
  1. 実行を伝播できない。(ノードは 待機状態 として動作します。)
  2. ノードの 退出遷移 の 1 つを介して実行を伝播できる。(これは、最初にノードに到達したトークンが、API 呼び出し executionContext.leaveNode(String) により 退出遷移 の 1 つを介して渡されることを意味します。) ノードは、いくつかのカスタムプログラミングロジックを実行し、待機せずにプロセスの実行を自動的に続行するという意味で、自動的に動作します。
  3. 新しいトークンの作成を "決定" できる。新しい各トークンは、新しい実行パスを表します。これらの新しいトークンはそれぞれ、ノードの 退出遷移 を介して起動できます。この種の動作の良い例は フォークノード です。
  4. 実行パスを終了できる。これは、トークンが終了したことを意味します。
  5. プロセスインスタンスの ランタイム構造 全体を変更できる。ランタイム構造は、トークンのツリーを含むプロセスインスタンスであり、それぞれが実行パスを表します。ノードは、トークンを作成および終了し、各トークンをグラフのノードに配置し、遷移を介してトークンを起動できます。
Business Process Manager には、事前に実装された一連のノードタイプが含まれており、それぞれに特定の設定と動作があります。ただし、独自のノード動作を記述してプロセスで使用することもできます。

6.3.2. ノードタイプ: タスクノード

タスクノード は、手動で実行する必要がある 1 つ以上のタスクを表します。そのため、実行プロセスがノードに到達すると、ワークフロー参加者に属するリストにタスクインスタンスが作成されます。その後、ノードは 待機状態 に入ります。ユーザーがタスクを完了すると、実行がトリガーされて再開されます。

6.3.3. ノードタイプ: 状態

状態 は "必要最小限" の 待機状態 です。これは、どのタスクリストに対してもタスクインスタンスが作成されないという点で、タスクノードとは異なります。これは、プロセスが外部システムを待機している場合に役立ちます。その後、プロセスは待機状態になります。外部システムが応答メッセージを送信すると、通常 token.signal() が呼び出され、プロセス実行の再開をトリガーします。

6.3.4. ノードタイプ: 決定

決定をモデル化する方法は 2 つあります。どちらを使用するかは、ユーザーの裁量に任されています。オプションは次のとおりです。
  1. プロセスによって決定を行う。そのため、決定をプロセス定義で指定する。
  2. 外部エンティティーによって決定を行う。
プロセスによって決定を行う場合は、決定ノード を使用します。2 つの方法のいずれかで決定基準を指定します。最も簡単な方法は、条件要素を遷移に追加することです。(条件は、ブール値を返す EL 式または Beanshell スクリプトです。)
ランタイム時に、決定ノードは、条件が指定されている 退出遷移 をループします。決定ノードは、XML で指定された順序でこれらの遷移を最初に評価します。条件が true に解決される最初の遷移が取得されます。すべての遷移の条件が false に解決された場合、デフォルトの遷移 (XML の最初の遷移) が代わりに取得されます。デフォルトの遷移が見つからない場合、JbpmException が出力されます。
2 つ目の方法は、取得する遷移の名前を返す式を使用することです。expression 属性を使用して、決定の式を指定します。この式は、決定ノードのいずれかの 退出遷移 に解決する必要があります。
また、決定で handler 要素を使用することもできます。この要素を使用すると、決定ノードで指定できる DecisionHandler インターフェイスを実装できます。このシナリオでは、決定は Java クラスによって計算され、選択された 退出遷移DecisionHandler 実装に属する decide メソッドによって返されます。
外部エンティティーによって決定を行う場合は、状態 または 待機状態 ノードから退出する複数の遷移を常に使用してください。待機状態 が完了した後に実行を再開する外部トリガーで退出遷移を指定できます (Token.signal(String transitionName)TaskInstance.end(String transitionName) など)。

6.3.5. ノードタイプ: フォーク

フォークは、単一の実行パスを複数の同時実行パスに分割します。デフォルトでは、フォークは、そこから退出する遷移ごとに子トークンを作成します (これにより、フォークに到達するトークン間に親子関係が作成されます)。

6.3.6. ノードタイプ: ジョイン

デフォルトでは、ジョインは、その内部に到達したすべてのトークンが同じ親の子であると想定します。(この状況は、上記のようにフォークを使用した場合、およびフォークによって作成されたすべてのトークンが同じジョインに到達した場合に発生します。)
ジョインは、それに進入するすべてのトークンを終了します。次に、それらのトークンの親子関係を調べます。すべての兄弟トークンがジョインに到達すると、親トークンは 退出遷移 に渡されます。アクティブな兄弟トークンがまだある場合、ジョインは 待機状態 として動作します。

6.3.7. ノードタイプ: ノード

このノードは、カスタムコードの作成を回避するために使用します。このノードには、1 つのサブ要素アクションのみが必要です。サブ要素アクションは、実行がノードに到達したときに実行されます。actionhandler に記述されたカスタムコードは、任意の処理を実行できますが、実行を渡す役割もあることに注意してください。詳細は、「 ノードの役割 」 を参照してください。
このノードは、Java API を利用して企業のビジネスアナリスト向けの機能ロジックを実装する場合にも使用できます。そのようにすると、ノードがプロセスのグラフィカル表現に表示されたままになるため、便利です。(プロセスのグラフィカル表現には表示されないコードを追加するには、アクションを使用します。)

6.4. 遷移

遷移には、ソースノードと宛先ノードの両方があります。ソースノードは、from プロパティー、宛先ノードは to プロパティーによって表されます。
必要に応じて、遷移に名前を付けることができます。(Business Process Manager のほとんどの機能は、遷移に固有の名前が付けられていることに依存しています。) 複数の遷移が同じ名前の場合、最初の遷移が取得されます。(ノードで遷移名が重複する場合、Map getLeavingTransitionsMap() メソッドは、List getLeavingTransitions() よりも少ない要素を返します。)

6.5. アクション

アクションは、プロセス実行中にイベントで実行される Java コードの一部です。グラフは、ソフトウェア要件の伝達において重要な手段です。しかし、グラフは作成中のソフトウェアの 1 つのビュー (プロジェクション) にすぎません。多くの技術的な詳細は、そこには表示されません。アクションは、グラフィカルな表現以外の技術的な詳細を追加するためのメカニズムです。グラフを配置したら、アクションで装飾することができます。これにより、グラフの構造を変更せずに Java コードをグラフに関連付けることができます。主なイベントタイプは、ノード進入、ノード退出、遷移取得です。
重要
イベントに配置されるアクションとノードに配置されるアクションには違いがあります。イベントに配置されたアクションは、イベントが発生したときに実行されます。このアクションには、プロセスの制御の流れに影響を与える方法はありません。(これは、オブザーバーパターン に似ています。) 対照的に、ノードに配置されたアクションには、実行を渡す役割があります。
このセクションでは、イベントに対するアクションの例を説明します。この例は、特定の遷移でデータベースの更新を行う方法を示しています。(データベースの更新は技術的には重要ですが、ビジネスアナリストにとっては重要ではありません。)

図6.2 データベース更新アクション

データベース更新アクション
public class RemoveEmployeeUpdate implements ActionHandler {
  public void execute(ExecutionContext ctx) throws Exception {
    // get the fired employee from the process variables.
    String firedEmployee =
      (String) ctx.getContextInstance().getVariable("fired employee");
    
    // by taking the same database connection as used for the jbpm
    // updates, we reuse the jbpm transaction for our database update.
    Connection connection =
    ctx.getProcessInstance().getJbpmSession().getSession().getConnection();
    Statement statement = connection.createStatement();
    statement.execute("DELETE FROM EMPLOYEE WHERE ...");
    statement.execute(); 
    statement.close();
  }
}
<process-definition name="yearly evaluation">
  <state name="fire employee">
    <transition to="collect badge">
      <action class="com.nomercy.hr.RemoveEmployeeUpdate" />
    </transition>
  </state>
  
  <state name="collect badge">
  
</process-definition>

6.5.1. アクションリファレンス

アクションには名前を付けることができます。これにより、アクションが指定されている他の場所からアクションを参照できます。名前付きアクションは、子要素 としてプロセス定義に追加することもできます。
この機能を使用して、アクション設定の重複を制限します。(これは、アクションの設定が複雑な場合や、ランタイムアクションをスケジュールまたは実行する必要がある場合に特に役立ちます。)

6.5.2. イベント

イベントは、プロセスの実行における特定の瞬間です。Business Process Manager のエンジンは、グラフ実行 中にイベントを "発生" させます。これは、ソフトウェアが次の状態を計算するとき (つまり、シグナルを処理するとき) に行われます。 イベントは常に、プロセス定義内の要素に関連しています。
ほとんどのプロセス要素は、さまざまなタイプのイベントを起動することができます。たとえば、ノードは node-enter イベントと node-leave イベントの両方を発生させることができます。(イベントはアクションの "フック" です。各イベントにはアクションのリストがあります。jBPM エンジンがイベントを発生させると、アクションのリストが実行されます。)

6.5.3. イベントの受け渡し

スーパーステート は、プロセス定義の要素に親子関係を作成します。(スーパーステートに含まれるノードと遷移は、そのスーパーステートを親として持ちます。最上位の要素はプロセス定義を親として持ち、プロセス定義自体はそれより上の親を持ちません。) イベントが発生すると、イベントは親階層に渡されます。これにより、プロセス内のすべての遷移イベントをキャプチャーし、一元化された場所を介してアクションをこれらのイベントに関連付けることができます。

6.5.4. スクリプト

スクリプト は、Beanshell スクリプトを実行するアクションです。(Beanshell の詳細は、http://www.beanshell.org/ を参照してください。) デフォルトでは、すべてのプロセス変数をスクリプト変数として使用できますが、スクリプト変数はプロセス変数に書き込まれません。使用できるスクリプト変数は次のとおりです。
  • executionContext
  • トークン (token)
  • node
  • task
  • taskInstance
<process-definition>
  <event type="node-enter">
    <script>
      System.out.println("this script is entering node "+node);
    </script>
  </event>
  ...
</process-definition>
スクリプトへの変数の読み込みと保存のデフォルトの動作をカスタマイズするには、variable 要素をスクリプトのサブ要素として使用します。その場合は、スクリプト式もサブ要素 expression としてスクリプトに配置します。
<process-definition>
  <event type="process-end">
    <script>
      <expression>
        a = b + c;
      </expression>
      <variable name='XXX' access='write' mapped-name='a' />
      <variable name='YYY' access='read' mapped-name='b' />
      <variable name='ZZZ' access='read' mapped-name='c' />
    </script>
  </event>
  ...
</process-definition>
スクリプトが起動する前に、プロセス変数 YYY および ZZZ が、それぞれスクリプト変数 b および c としてスクリプトで使用できるようになります。スクリプトが完了すると、スクリプト変数 a の値が、プロセス変数 XXX に格納されます。
変数の access 属性に read が含まれている場合、プロセス変数は、スクリプトが評価される前にスクリプト変数としてロードされます。access 属性に write が含まれている場合、スクリプト変数は評価後にプロセス変数として保存されます。mapped-name 属性を使用すると、スクリプト内でプロセス変数を別の名前で使用できます。これは、プロセス変数名にスペースやその他の無効な文字が含まれている場合に使用します。

6.5.5. カスタムイベント

GraphElement.fireEvent(String eventType, ExecutionContext executionContext); メソッドを呼び出すことで、プロセスの実行中に自由にカスタムイベントを実行できます。イベントタイプの名前は自由に選択してください。

6.6. スーパーステート

スーパーステートはノードのグループです。これらは再帰的にネストでき、プロセス定義に階層を追加するために使用されます。たとえば、この機能は、プロセスに属するノードをフェーズごとにグループ化するのに役立ちます。
アクションは、スーパーステートイベントに関連付けることができます。ネストされたノードのトークンによって発生したイベントは、プロセス定義までスーパーステート階層をバブルアップします。したがって、トークンは階層内のすべてのノードに同時に存在するものとして機能します。これは、たとえば、プロセス実行が起動フェーズにあるかどうかを確認する場合に便利です。

6.6.1. スーパーステート遷移

スーパーステートから退出する遷移は、そのスーパーステート内の任意のノードに配置されたトークンによって取得できます。この機能は、随時取得できる キャンセル 遷移のモデル化などに使用できます。
遷移はスーパーステートにも到達することがあります。その場合、トークンはドキュメント順の最初のノードにリダイレクトされます。さらに、スーパーステートの外側にあるノードは、スーパーステートの内側にあるノードに直接遷移することができ、逆もまた同様です。最後に、他のノードと同様に、スーパーステートも自己遷移できます。

6.6.2. スーパーステートイベント

スーパーステートには、superstate-enter および superstate-leave という固有のイベントが 2 つあります。これらのイベントは、ノードがどの遷移に進入したか、またはどの遷移から退出したかに関係なく、発生します。スーパーステート内でトークンが遷移を取得する限り、これらのイベントは発生しません。
注記
ステートとスーパーステートには別々のイベントタイプがあります。このソフトウェアは、実際のスーパーステートイベントとスーパーステート内から渡されたノードイベントを簡単に区別できるように設計されています。

6.6.3. 階層名

ノード名は、スコープ 内で一意である必要があります。ノードのスコープは、その ノードコレクション です。プロセス定義とスーパーステートは、どちらもノードコレクションです。スーパーステートのノードを参照するには、スラッシュ (/) 区切りの相対名で指定します。ノード名はスラッシュで区切られます。.. を使用して、上位レベルを参照します。次の例は、スーパーステートのノードを参照する方法を示しています。
<process-definition>
  <state name="preparation">
    <transition to="phase one/invite murphy"/>
  </state>
  <super-state name="phase one">
    <state name="invite murphy"/>
  </super-state>
</process-definition>
次の例は、スーパーステート階層を上に移動する方法を示しています。
<process-definition>
  <super-state name="phase one">
    <state name="preparation">
      <transition to="../phase two/invite murphy"/>
    </state>
  </super-state>
  <super-state name="phase two">
    <state name="invite murphy"/>
  </super-state>
</process-definition>

6.7. 例外処理

Business Process Manager の例外処理メカニズムは、Java 例外に対してのみ機能します。グラフ実行自体が問題を引き起こすことはありません。例外が発生する可能性があるのは、委譲クラス が実行されたときだけです。
exception-handler のリストは、process-definitionnodetransition で指定できます。これらの各例外ハンドラーには、アクションのリストがあります。委譲クラスで例外が発生すると、プロセス要素の親階層で適切な exception-handler が検索され、そのアクションが実行されます。
重要
Business Process Manager の例外処理は、Java の例外処理といくつかの点で異なります。Java では、キャッチされた例外が 制御フロー に影響を与える可能性があります。jBPM の場合、例外処理メカニズムが制御フローを変更することはできません。例外は、キャッチされるか、キャッチされないかのいずれかです。キャッチされていない例外は、token.signal() メソッドを呼び出したクライアントに出力されます。キャッチされた例外がある場合は、何も発生しなかったかのようにグラフ実行が続行されます。
注記
例外処理 アクション のグラフ内にある任意のノードにトークンを配置するには、Token.setNode(Node node) を使用します。

6.8. プロセス構成

Business Process Manager は、process-state によって プロセス構成 をサポートしています。この状態は、別のプロセス定義に関連付けられている状態です。グラフ実行が process-state に到達すると、サブプロセスの新しいインスタンスが作成されます。このサブプロセスは、プロセス状態に到達した実行パスに関連付けられます。スーパープロセスの実行パスは、サブプロセスが終了するまで待機し、その後プロセス状態から退出し、スーパープロセスでグラフ実行を継続します。
<process-definition name="hire">
  <start-state>
    <transition to="initial interview" />
  </start-state>
  <process-state name="initial interview">
    <sub-process name="interview" />
    <variable name="a" access="read,write" mapped-name="aa" />
    <variable name="b" access="read" mapped-name="bb" />
    <transition to="..." />
  </process-state>
  ...
</process-definition>
上記の例では、hire プロセスには、interview プロセスを生成する process-state が含まれています。first interview に実行が到達すると、interview プロセスの新しい実行 (つまり、プロセスインスタンス) が作成されます。バージョンが明示的に指定されていない場合、サブプロセスの最新バージョンが使用されます。Business Process Manager で特定のバージョンをインスタンス化するには、オプションの version 属性を指定します。サブプロセスが実際に作成されるまで、指定したバージョンまたは最新バージョンのバインドを延期するには、オプションの binding 属性を late に設定します。
次に、hire プロセス変数 ainterview プロセス変数 aa にコピーします。同様に、hire 変数 b を インタビュー変数 bb にコピーします。面接プロセスが完了すると、変数 aa のみが a 変数に再びコピーされます。
一般に、サブプロセスが開始されると、読み取りアクセス権を持つすべての変数がスーパープロセスから読み取られ、新しく作成されたサブプロセスに取り込まれます。これは、開始状態から退出するシグナルが与えられる前に行われます。サブプロセスインスタンスが完了すると、書き込みアクセス権を持つすべての変数がサブプロセスからスーパープロセスにコピーされます。変数の mapped-name 属性を使用して、サブプロセスで使用する変数名を指定します。

6.9. カスタムノードの動作

任意のビジネスロジックを実行できるだけでなく、グラフ実行を渡す役割を持つ ActionHandler の特別な実装を使用して、カスタムノードを作成します。以下の例では、ERP システムから値を読み取り、(プロセス変数から) 金額を追加し、結果を ERP システムに保存します。金額の大きさに基づいて、 small amounts 遷移または large amounts 遷移を使用して終了します。

図6.3 ERP 更新用のプロセススニペットの例

ERP 更新用のプロセススニペットの例
public class AmountUpdate implements ActionHandler {
  public void execute(ExecutionContext ctx) throws Exception {
    // business logic
    Float erpAmount = ...get amount from erp-system...;
    Float processAmount = (Float) ctx.getContextInstance().getVariable("amount");
    float result = erpAmount.floatValue() + processAmount.floatValue();
    ...update erp-system with the result...;
    
    // graph execution propagation
    if (result > 5000) {
      ctx.leaveNode(ctx, "big amounts");
    } else {
      ctx.leaveNode(ctx, "small amounts");
    }
  }
}
注記
カスタムノード実装でトークンを作成して結合することもできます。これを行う方法については、jBPM ソースコードのフォークノードおよびジョインノードの実装を参照してください。

6.10. グラフ実行

Business Process Manager のグラフ実行モデルは、プロセス定義の解釈と "チェーンオブコマンド" パターンに基づいています。
プロセス定義データはデータベースに格納され、プロセス実行中に使用されます。
注記
ランタイム時に定義情報をロードしないように、Hibernate の 2 次キャッシュが使用されることに注意してください。プロセス定義は変更されないため、Hibernate はそれらをメモリーにキャッシュできます。
"チェーンオブコマンドパターン" は、グラフ内の各ノードにプロセス実行の受け渡しを担当させます。ノードがプロセス実行を渡さない場合、ノードは 待機状態 のように動作します。
プロセスインスタンスで実行を開始すると、実行は 待機状態 に進入するまで続行されます。
トークンは実行のパスを表します。トークンには、プロセスグラフ内のノードへのポインターがあります。トークンは、待機状態 の間、データベースで永続化することができます。
このアルゴリズムは、トークンの実行を計算するために使用されます。シグナルがトークンに送信されると実行が開始され、コマンドオブチェーンパターンを介して遷移とノードに渡されます。関連するメソッドは次のとおりです。

図6.4 グラフ実行関連のメソッド

グラフ実行関連のメソッド
トークンがノードにあるとき、そのトークンにシグナルを送信できます。シグナルは実行開始の命令として扱われるため、トークンの現在のノードからの 退出遷移 を指定する必要があります。最初の遷移がデフォルトです。トークンにシグナルが送信されると、遷移はトークンの現在のノードを取得し、Node.leave(ExecutionContext,Transition) メソッドを呼び出します。(ExecutionContext は、その中の主要なオブジェクトがトークンであるため、トークンと考えるのが最適です。) Node.leave(ExecutionContext,Transition) メソッドは node-leave イベントを発生させ、Transition.take(ExecutionContext) を呼び出します。このメソッドは遷移イベントを実行し、遷移の宛先ノードで Node.enter(ExecutionContext) を呼び出します。さらに、このメソッドが node-enter イベントを発生させ、Node.execute(ExecutionContext) を呼び出します。
すべてのタイプのノードには独自の動作があります。これらは execute メソッドを介して実装されます。各ノードには、Node.leave(ExecutionContext,Transition) を再度呼び出して、グラフ実行を受け渡す役割があります。つまり、以下のようになります。
  • Token.signal(Transition)
  • Node.leave(ExecutionContext,Transition)
  • Transition.take(ExecutionContext)
  • Node.enter(ExecutionContext)
  • Node.execute(ExecutionContext)
注記
次の状態 (アクションの呼び出しを含む) は、クライアントのスレッドを介して計算されます。よくある誤解として、すべての計算をこの方法で行う必要があるというものがあります。むしろ、非同期呼び出し の場合と同様に、非同期メッセージング を (Java Message Service 経由で) 使用できます。メッセージがプロセスインスタンスの更新と同じトランザクションで送信されると、すべての同期の問題が正しく処理されます。一部のワークフローシステムは、グラフ内のすべてのノード間で非同期メッセージングを使用しますが、高スループット環境では、このアルゴリズムは、ビジネスプロセスのパフォーマンスを最大化を求めるユーザーに、はるかに多くの制御と柔軟性を提供します。

6.11. トランザクションの境界

「 グラフ実行 」 で説明したように、Business Process Manager はクライアントのスレッドでプロセスを実行し、その性質上、同期的です。実際には、これはつまり、プロセスが新しい 待機状態 に進入したときにのみ、token.signal() または taskInstance.end() が返されることを意味します。
注記
このセクションで説明されている jPDL 機能の詳細は、10章 非同期継続 を参照してください。
プロセスの実行をサーバー側のトランザクションに簡単にバインドできるため、ほとんどの場合、これが最も単純なアプローチです。プロセスは、1 つのトランザクションの空間内で 1 つの状態から次の状態に移動します。
処理中の計算には時間がかかる場合があるため、この動作は望ましくない場合があります。この問題に対処するために、Business Process Mangerには非同期メッセージングシステムが組み込まれています。このシステムは、その名前が示すように非同期でプロセスを続行できます。(もちろん、Java エンタープライズ環境では、組み込みのメッセージングシステムの代わりに Java Message Service ブローカーを使用するように jBPM を設定できます。)
jPDL は、すべてのノードで async="true" 属性をサポートします。非同期ノードは、クライアントのスレッドでは実行されません。代わりに、非同期メッセージングシステムを介してメッセージが送信され、スレッドがクライアントに返されます (つまり、token.signal() または taskInstance.end() が返されます。)
Business Process Manger のクライアントコードは、トランザクションをコミットできます。プロセスの更新を含むトランザクションと同じトランザクションでメッセージを送信します。このようなトランザクションの全体的な結果として、トークンは次のノード (まだ実行されていないノード) に移動され、org.jbpm.command.ExecuteNodeCommand メッセージが非同期メッセージングシステムから jBPM Command Executor に送信されます。これにより、キューからコマンドが読み取られ、実行されます。org.jbpm.command.ExecuteNodeCommand の場合、ノード実行時に処理が継続されます。(各コマンドは別々のトランザクションで実行されます。)
重要
非同期プロセスを続行できるように、jBPM Command Executor が実行されていることを確認してください。これを行うには、Web アプリケーションの CommandExecutionServlet を設定します。
注記
プロセスモデル管理者は、非同期メッセージングに過度に配慮する必要はありません。覚えておくべき主なポイントは、トランザクションの境界です。デフォルトでは、Business Process Manger はクライアントトランザクションで動作し、プロセスが 待機状態 に進入するまで計算全体を実行します。(async="true" を使用して、プロセス内のトランザクションを区別します。)
以下に例を示します。
<start-state>
  <transition to="one" />
</start-state>
<node async="true" name="one">
  <action class="com...MyAutomaticAction" />
  <transition to="two" />
</node>
<node async="true" name="two">
  <action class="com...MyAutomaticAction" />
  <transition to="three" />
</node>
<node async="true" name="three">
  <action class="com...MyAutomaticAction" />
  <transition to="end" />
</node>
<end-state name="end" />
...
プロセス実行の開始と再開の両方に必要なクライアントコードは、通常の同期プロセスに必要なコードとまったく同じです。
//start a transaction
JbpmContext jbpmContext = jbpmConfiguration.createContext();
try {
  ProcessInstance processInstance =
    jbpmContext.newProcessInstance("my async process");
  processInstance.signal();
  jbpmContext.save(processInstance);
} finally {
  jbpmContext.close();
}
この最初のトランザクションが発生すると、プロセス実行の root tokennode one を参照し、ExecuteNodeCommand メッセージがコマンドエグゼキューターに送信されます。
後続のトランザクションで、コマンドエグゼキューターはキューからメッセージを読み取り、node one を実行します。アクションは、実行を渡すか、待機状態 に進入するかを決定できます。実行を渡すことを選択した場合、実行が node two に到達したときにトランザクションは終了します。
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2026 Red Hat
トップに戻る