子流程

概览

子流程(Subprocess) 也是一个活动,其中可以包含其他活动、网关、事件等, 这些子元素又形成了一个流程,而这个流程是更大流程的一部分。 使用子流程可以对工作流进行分层建模,从而构建业务流程的高级端到端概览。 子流程可以嵌套。

但是,子流程会创建一个流程变量和 事件 的新 作用域。 子流程执行过程中抛出的事件可以由子流程边界的边界事件捕获, 为事件创建一个子流程范围的作用域。

Jmix BPM 中有三种类型的子流程:

subprocess types

嵌入子流程

在父流程中定义的子流程称为嵌入子流程。 嵌入子流程不可重用。 也就是说,不能在流程的其他地方调用该子流程。 这种子流程是父流程的一部分。

图形表示法

子流程展示为一个圆角矩形,与任务类似,但是尺寸更大。 如需创建子流程,从工具箱选择 icon subprocess,然后放置到画布中。

create subprocess

然后,可以将已有元素拖放到子流程中或创建新的元素。 嵌入子流程只能有一个 '空启动事件';不允许使用其他类型的启动事件。

XML 表示

嵌入子流程 subProcess 元素定义。 属于子流程的所有活动、网关、事件等,都需要包含在此元素中。

<subProcess id="Activity_17a4us1" name="Subprocess">
  <startEvent id="subProcessStart" />

... other subprocess elements ...

  <endEvent id="subProcessEnd" />
 </subProcess>
属性

嵌入子流程没有特殊属性,只有通用属性。可以设置名称,名称将在图中显示为标签。

subprocess properties

子流程也可以是 异步多实例 的。

事件子流程

事件子流程(Event subprocess) 是一个由事件触发的子流程。 可以在流程级别或其他子流程级别添加。

用于触发事件子流程的事件是使用启动事件配置的。 事件子流程可以通过事件触发,例如消息事件、错误事件、信号事件、定时器事件或补偿事件。 在事件子流程的父作用域(流程实例或子流程)创建时,会开始订阅启动事件。 父作用域销毁时,将解除订阅。

图形表示法

事件子流程在图中显示为虚线轮廓的圆角矩形。 如需创建事件子流程,添加一个嵌入子流程,然后将其更改为事件子流程:

creating event subprocess

然后可以继续设计子流程

creating event subprocess 2

事件子流程不支持 空启动事件。 尽管在部署或运行时不会造成任何异常,但是这个子流程将无法触发。

XML 表示

事件子流程的 XML 元素与嵌入子流程相同。 但是,属性 triggeredByEvent 的值必须为 true

<subProcess id="event-subprocess" name="Event subprocess" triggeredByEvent="true"> (1)
  <sequenceFlow id="Flow_14hzcqy" sourceRef="start-message-event" targetRef="Activity_0iuoq5t" />
  <startEvent id="start-message-event"> (2)
    <messageEventDefinition id="MessageEventDefinition_1hzz5hc" messageRef="cancel-order" />
  </startEvent>

... other subprocess elements ...

</subProcess>
1  — triggeredByEvent 属性
2  — 消息启动事件
示例

下面的示例是使用 错误启动事件 触发的事件子流程。 事件子流程是 “流程级别” 的,即,其作用域限定为流程实例中:

event subprocess example

事件子流程可以在嵌入子流程中定义。 在这种情况下,当触发错误事件时,事件子流程将有权访问子流程的局部变量:

event subprocess error

当使用错误边界事件时,外部事件处理器看不到局部变量:

subprocess error

事务子流程

事务子流程(transaction subprocess) 是一个嵌入子流程,可以用来将多个活动绑定至一个事务中。 事务是一个工作逻辑单元,可以对独立的活动进行分组, 组内的活动要么同时成功,要么同时失败。

图形表示法

事务子流程在图中显示为具有双线边框的圆角矩形。 如需创建事务子流程,添加一个嵌入式流程,然后将其更改为事务子流程:

transaction subprocess
XML 表示

事务子流程在 XML 中使用 transaction 标签:

<transaction id="transaction-subprocess" name="Transaction subprocess">
  . . .
</transaction>
事务的坑输出

事务可以有三种不同的输出:

成功

如果事务子流程以正常方式完成,则是成功的,然后主流程按照传出顺序流继续。 如果在流程后续的过程中引发补偿事件,则成功的事务也可能会得到补偿。

与 “普通” 的嵌入子流程一样,事务子流程可以在成功完成后使用中间抛出补偿事件进行补偿。

取消

如果流程执行到 取消结束事件,则事务将被视为已取消。 此时,终止并删除所有的执行过程。 然后,将仅剩的一个指向过程设置为取消边界事件,从而触发补偿。 补偿完成后,流程将使用取消边界事件的传出顺序流离开事务子流程。

危险

如果抛出的 错误事件 没有在事务子流程的范围内捕获,则事务将由于出现危险而结束。 如果错误在事件子流程的边界捕获,也是危险的结果。 在这些情况下,不会执行补偿。

transaction subprocess example

不要将 BPMN 的事务子流程与技术上的事务(ACID,如数据库事务)混淆。 详情参阅 BPMN 事务

调用活动

调用活动(Call Activity) 是一种调用可重用流程、 或另一个流程中全局任务的活动。 提供了一种将复杂流程分解为更小、更易于管理的方法,并提高了可重用性。

与嵌入子流程相反,调用活动 是一个 外部 子流程。

当流程执行到达调用活动时, 将创建一个新的执行过程,该过程是到达调用活动的执行过程的子过程。 然后,用该子过程执行子流程,可能创建并行子执行过程,与在常规流程中一样。 父执行过程会等到子流程完全结束,然后继续执行原始流程。

图形表示法

调用活动与普通任务一样,在图中显示为一个圆角矩形, 但是边框为粗线,且内部有一个子流程 标记

call activity
XML 表示

调用活动是一个常规活动,需要使用 calledElement 引用流程定义。 实际上,calledElement 中使用的是流程的 ID。

<callActivity id="Activity_08ermzt" name="Call activity"
              calledElement="data-task-sample" (1)
              flowable:inheritBusinessKey="true"> (2)
  <extensionElements>
    <flowable:in sourceExpression="${client.name}" (3)
                 target="clientName" />
    <flowable:out source="clientName"  (4)
                  target="clientName" />
  </extensionElements>
  <incoming>Flow_0sdrrfm</incoming>
</callActivity>
1  — 调用活动元素,默认用流程 ID(流程定义键值)
2  — 继承业务键值
3  — 输入映射使用表达式
4  — 输出映射使用变量

子流程的流程定义在运行时进行解析。 因此,如果需要的话,子流程可以独立于调用流程进行单独部署。

属性

调用活动可以通过设置属性进行配置:

call activity properties
  • Called Element:已有流程的引用。

    请避免未管理的递归!从技术上讲,可以从自身内部调用该流程的另一个实例。
  • Called Element Type:在 Studio 中,默认情况下,使用 key 参数。也就是说,调用流程的最后一个版本。

    在 Web 建模器中,可以通过 id 指定调用流程的特定版本。

  • Business Key:可以用表达式定义或从父流程继承。 参阅 BPM 概念

  • Variables Mapping

    • 首先,调用活动可以从父流程继承流程变量。 即,当被调用的流程启动时,将在其中创建流程变量,就像在父流程中一样, 但这些变量是新的实例,而不是对原始实例的引用。

    • In Mapping:在这里,可以使用已有流程变量(source)将参数传递到被调用流程(target)中的变量:

      in mapping

      或者通过表达式:

      in mapping expression
    • Out Mapping:这里,可以将被调用流程(source)中的变量映射到父流程(target)中的变量:

      out mapping

      或者使用表达式。

调用活动中的用户任务

如果被调用的流程有 用户任务,则任务的执行人可以在任务列表(我的任务(My tasks))中看到这些任务, 但这些任务在被调用累成的名称下,而不是父流程的名称下。 所以在创建流程时使用业务键值(business key)非常重要。

因此,如果需要管理流程中的所有任务,并且流程有调用活动,则应注意这一点。