并行网关

描述

网关也可以表示流程中的并行情况。最简单的并行网关是 并行网关,它允许将流程 分成多条分支,也可以把多条分支 汇聚到一起。 of execution.

并行网关的功能是基于进入和外出的顺序流的:

  • 分支: 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
  • 汇聚: 所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。

注意,如果同一个并行网关有多个进入和多个外出顺序流, 它就同时具有分支和汇聚功能。这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。

与其他网关的主要区别是,并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。

图形标记

并行网关显示成一个普通网关(菱形)内部是一个“加号”图标, 表示“与(AND)”语义。

并行网关图标

XML

定义并行网关只需要一行XML:

<parallelGateway id="myParallelGateway" />

实际发生的行为(分支,聚合,同时分支聚合), 要根据并行网关的顺序流来决定。

参考如下代码:

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

    <parallelGateway id="fork" />
    <sequenceFlow sourceRef="fork" targetRef="receivePayment" />
    <sequenceFlow sourceRef="fork" targetRef="shipOrder" />

    <userTask id="receivePayment" name="Receive Payment" />
    <sequenceFlow sourceRef="receivePayment" targetRef="join" />

    <userTask id="shipOrder" name="Ship Order" />
    <sequenceFlow sourceRef="shipOrder" targetRef="join" />

    <parallelGateway id="join" />
    <sequenceFlow sourceRef="join" targetRef="archiveOrder" />

    <userTask id="archiveOrder" name="Archive Order" />
    <sequenceFlow sourceRef="archiveOrder" targetRef="theEnd" />

    <endEvent id="theEnd" />

上面例子中,流程启动之后,会创建两个任务:

ProcessInstance pi = runtimeService.startProcessInstanceByKey("forkJoin");
TaskQuery query = taskService.createTaskQuery()
                         .processInstanceId(pi.getId())
                         .orderByTaskName()
                         .asc();

List<Task> tasks = query.list();
assertEquals(2, tasks.size());

Task task1 = tasks.get(0);
assertEquals("Receive Payment", task1.getName());
Task task2 = tasks.get(1);
assertEquals("Ship Order", task2.getName());

当两个任务都完成时,第二个并行网关会汇聚两个分支,因为它只有一条外出连线, 不会创建并行分支, 只会创建归档订单任务。

注意并行网关不需要是“平衡的”(比如, 对应并行网关的进入和外出节点数目相等)。 并行网关只是等待所有进入顺序流,并为每个外出顺序流创建并发分支, 不会受到其他流程节点的影响。 所以下面的流程在BPMN 2.0中是合法的:

排他网关图例