子流程
概览
子流程(Subprocess) 也是一个活动,其中可以包含其他活动、网关、事件等, 这些子元素又形成了一个流程,而这个流程是更大流程的一部分。 使用子流程可以对工作流进行分层建模,从而构建业务流程的高级端到端概览。 子流程可以嵌套。
Jmix BPM 中有三种类型的子流程:
嵌入子流程
在父流程中定义的子流程称为嵌入子流程。 嵌入子流程不可重用。 也就是说,不能在流程的其他地方调用该子流程。 这种子流程是父流程的一部分。
子流程展示为一个圆角矩形,与任务类似,但是尺寸更大。 如需创建子流程,从工具箱选择 ,然后放置到画布中。
然后,可以将已有元素拖放到子流程中或创建新的元素。 嵌入子流程只能有一个 '空启动事件';不允许使用其他类型的启动事件。
嵌入子流程 subProcess 元素定义。 属于子流程的所有活动、网关、事件等,都需要包含在此元素中。
<subProcess id="Activity_17a4us1" name="Subprocess">
<startEvent id="subProcessStart" />
... other subprocess elements ...
<endEvent id="subProcessEnd" />
</subProcess>
嵌入子流程没有特殊属性,只有通用属性。可以设置名称,名称将在图中显示为标签。
事件子流程
事件子流程(Event subprocess) 是一个由事件触发的子流程。 可以在流程级别或其他子流程级别添加。
用于触发事件子流程的事件是使用启动事件配置的。 事件子流程可以通过事件触发,例如消息事件、错误事件、信号事件、定时器事件或补偿事件。 在事件子流程的父作用域(流程实例或子流程)创建时,会开始订阅启动事件。 父作用域销毁时,将解除订阅。
事件子流程在图中显示为虚线轮廓的圆角矩形。 如需创建事件子流程,添加一个嵌入子流程,然后将其更改为事件子流程:
然后可以继续设计子流程
事件子流程不支持 空启动事件。 尽管在部署或运行时不会造成任何异常,但是这个子流程将无法触发。 |
事件子流程的 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 | — 消息启动事件 |
下面的示例是使用 错误启动事件 触发的事件子流程。 事件子流程是 “流程级别” 的,即,其作用域限定为流程实例中:
事件子流程可以在嵌入子流程中定义。 在这种情况下,当触发错误事件时,事件子流程将有权访问子流程的局部变量:
当使用错误边界事件时,外部事件处理器看不到局部变量:
事务子流程
事务子流程(transaction subprocess) 是一个嵌入子流程,可以用来将多个活动绑定至一个事务中。 事务是一个工作逻辑单元,可以对独立的活动进行分组, 组内的活动要么同时成功,要么同时失败。
事务子流程在图中显示为具有双线边框的圆角矩形。 如需创建事务子流程,添加一个嵌入式流程,然后将其更改为事务子流程:
事务子流程在 XML 中使用 transaction
标签:
<transaction id="transaction-subprocess" name="Transaction subprocess">
. . .
</transaction>
事务可以有三种不同的输出:
- 成功
-
如果事务子流程以正常方式完成,则是成功的,然后主流程按照传出顺序流继续。 如果在流程后续的过程中引发补偿事件,则成功的事务也可能会得到补偿。
与 “普通” 的嵌入子流程一样,事务子流程可以在成功完成后使用中间抛出补偿事件进行补偿。
- 取消
-
如果流程执行到 取消结束事件,则事务将被视为已取消。 此时,终止并删除所有的执行过程。 然后,将仅剩的一个指向过程设置为取消边界事件,从而触发补偿。 补偿完成后,流程将使用取消边界事件的传出顺序流离开事务子流程。
- 危险
-
如果抛出的 错误事件 没有在事务子流程的范围内捕获,则事务将由于出现危险而结束。 如果错误在事件子流程的边界捕获,也是危险的结果。 在这些情况下,不会执行补偿。
不要将 BPMN 的事务子流程与技术上的事务(ACID,如数据库事务)混淆。 详情参阅 BPMN 事务。 |
调用活动
调用活动(Call Activity) 是一种调用可重用流程、 或另一个流程中全局任务的活动。 提供了一种将复杂流程分解为更小、更易于管理的方法,并提高了可重用性。
与嵌入子流程相反,调用活动 是一个 外部 子流程。
当流程执行到达调用活动时, 将创建一个新的执行过程,该过程是到达调用活动的执行过程的子过程。 然后,用该子过程执行子流程,可能创建并行子执行过程,与在常规流程中一样。 父执行过程会等到子流程完全结束,然后继续执行原始流程。
调用活动与普通任务一样,在图中显示为一个圆角矩形, 但是边框为粗线,且内部有一个子流程 标记:
调用活动是一个常规活动,需要使用 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 | — 输出映射使用变量 |
子流程的流程定义在运行时进行解析。 因此,如果需要的话,子流程可以独立于调用流程进行单独部署。 |
调用活动可以通过设置属性进行配置:
-
Called Element:已有流程的引用。
请避免未管理的递归!从技术上讲,可以从自身内部调用该流程的另一个实例。 -
Called Element Type:在 Studio 中,默认情况下,使用 key 参数。也就是说,调用流程的最后一个版本。
在 Web 建模器中,可以通过 id 指定调用流程的特定版本。
-
Business Key:可以用表达式定义或从父流程继承。 参阅 BPM 概念。
-
Variables Mapping:
-
首先,调用活动可以从父流程继承流程变量。 即,当被调用的流程启动时,将在其中创建流程变量,就像在父流程中一样, 但这些变量是新的实例,而不是对原始实例的引用。
-
In Mapping:在这里,可以使用已有流程变量(source)将参数传递到被调用流程(target)中的变量:
或者通过表达式:
-
Out Mapping:这里,可以将被调用流程(source)中的变量映射到父流程(target)中的变量:
或者使用表达式。
-