本内容参考官网:官网文档
1 活动
事件用于模拟在流程生命周期中发生的事情。事件总是可视化为圆圈。在BPMN 2.0中,存在两个主要事件类别:捕获和抛出事件。
- **捕获:**当流程执行到达事件时,它将等待触发发生。触发器的类型由XML中的内部图标或类型声明定义。通过未填充的内部图标(它只是白色)在视觉上区分捕捉事件。
- **投掷:**当进程执行到达事件时,触发器被触发。触发器的类型由XML中的内部图标或类型声明定义。通过填充黑色的内部图标在视觉上区分投掷事件。
1.1.1 事件定义
事件定义定义事件的语义。没有事件定义,事件“没有什么特别之处”。例如,没有事件定义的启动事件没有指定究竟启动进程的内容。如果我们向start事件添加一个事件定义(例如,一个timer事件定义),我们声明事件的“type”启动过程(在一个定时器事件定义的情况下,某个时间点的事实是到达)。
1.1.2 定时器事件定义
计时器事件是由定义的计时器触发的事件。它们可以用作开始事件,中间事件或边界事件。时间事件的行为取决于使用的业务日历。每个计时器事件都有一个默认的业务日历,但业务日历也可以作为计时器事件定义的一部分给出。
<timerEventDefinition flowable:businessCalendarName="custom">
...
</timerEventDefinition>
其中businessCalendarName指向流程引擎配置中的业务日历。省略业务日历时,将使用默认业务日历。
计时器定义必须具有以下一个元素:
- timeDate。此格式以ISO 8601格式指定固定日期,此时将触发触发器。例如:
<timerEventDefinition>
<timeDate>2011-03-11T12:13:14</timeDate>
</timerEventDefinition>
- timeDuration。要指定计时器在触发之前应运行多长时间,可以将timeDuration指定为timerEventDefinition的子元素。使用的格式是ISO 8601格式(根据BPMN 2.0规范的要求)。例如(间隔持续10天):
<timerEventDefinition>
<timeDuration>P10D</timeDuration>
</timerEventDefinition>
- timeCycle。指定重复间隔,这对于定期启动进程或为过期用户任务发送多个提醒非常有用。时间周期元素可以是两种格式之一。首先,是ISO 8601标准规定的经常性持续时间的格式。示例(3个重复间隔,每个持续10个小时):
也可以将endDate指定为timeCycle上的可选属性,或者在时间表达式的末尾指定,如下所示:R3/PT10H/${EndDate}
。到达endDate时,应用程序将停止为此任务创建其他作业。它接受静态值ISO 8601标准的值,例如*“2015-02-25T16:42:11 + 00:00”,或变量,例如$ {EndDate}*
<timerEventDefinition>
<timeCycle flowable:endDate="2015-02-25T16:42:11+00:00">R3/PT10H</timeCycle>
</timerEventDefinition>
<timerEventDefinition>
<timeCycle>R3/PT10H/${EndDate}</timeCycle>
</timerEventDefinition>
如果同时指定了两者,则系统将使用指定为属性的endDate。
目前,只有BoundaryTimerEvents和CatchTimerEvent支持EndDate功能。
此外,您可以使用cron表达式指定时间周期; 以下示例显示从完整小时开始每5分钟触发一次:
0 0/5 * * *?
请参阅本教程以了解如何使用cron表达式。
**注意:**第一个符号表示秒,而不是正常Unix cron中的分钟。
循环持续时间更适合处理相对定时器,相对于某个特定时间点(例如,用户任务启动的时间)计算相对定时器,而cron表达式可以处理绝对定时器,这对于计时器启动事件。
您可以将表达式用于计时器事件定义,通过这样做,您可以根据流程变量影响计时器定义。对于适当的计时器类型,过程变量必须包含ISO 8601(或循环类型的cron)字符串。另外,对于持续时间,java.time.Duration
可以使用返回的类型或表达式的变量。
<boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport">
<timerEventDefinition>
<timeDuration>${duration}</timeDuration>
</timerEventDefinition>
</boundaryEvent>
**注:**计时器,只有当启用了异步执行(烧制asyncExecutorActivate必须设置为true
中flowable.cfg.xml
,因为异步执行默认情况下禁用)。
1.1.3 错误事件定义
重要说明: BPMN错误与Java异常不同。事实上,两者没有任何共同之处。BPMN错误事件是一种建模业务异常的方法。Java异常以其自己的特定方式处理。
<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="myError" />
</endEvent>
1.1.4 信号事件定义
信号事件是引用命名信号的事件。信号是全局范围的事件(广播语义),并传递给所有活动的处理程序(等待进程实例/捕获信号事件)。
使用该signalEventDefinition
元素声明信号事件定义。该属性signalRef
引用signal
声明为definitions
根元素的子元素的元素。以下是一个过程的摘录,其中信号事件被中间事件抛出并捕获。
<definitions... >
<!-- declaration of the signal -->
<signal id="alertSignal" name="alert" />
<process id="catchSignal">
<intermediateThrowEvent id="throwSignalEvent" name="Alert">
<!-- signal event definition -->
<signalEventDefinition signalRef="alertSignal" />
</intermediateThrowEvent>
...
<intermediateCatchEvent id="catchSignalEvent" name="On Alert">
<!-- signal event definition -->
<signalEventDefinition signalRef="alertSignal" />
</intermediateCatchEvent>
...
</process>
</definitions>
所述signalEventDefinition
参考中相同的signal
元件。
投掷信号事件
信号可以由流程实例使用BPMN构造抛出,也可以使用java API以编程方式抛出。以下方法org.flowable.engine.RuntimeService
可用于以编程方式抛出信号:
RuntimeService.signalEventReceived(String signalName);
RuntimeService.signalEventReceived(String signalName, String executionId);
signalEventReceived(String signalName)
和之间的区别在于signalEventReceived(String signalName, String executionId)
第一种方法将信号全局抛出到所有预订处理程序(广播语义),第二种方法仅将信号传递给特定执行。
捕捉信号事件
信号事件可以被中间捕获信号事件或信号边界事件捕获。
查询信号事件订阅
可以查询已订阅特定信号事件的所有执行:
List<Execution> executions = runtimeService.createExecutionQuery()
.signalEventSubscriptionName("alert")
.list();
然后我们可以使用该signalEventReceived(String signalName, String executionId)
方法将信号传递给这些执行。
信号事件范围
默认情况下,信号是广播流程引擎。这意味着您可以在流程实例中抛出信号事件,而具有不同流程定义的其他流程实例可以对此事件的发生做出反应。
但是,有时需要仅在同一个流程实例中对信号事件作出反应。例如,用例是当两个或多个活动互斥时流程实例中的同步机制。
要限制信号事件的范围,请将(非BPMN 2.0标准!)范围属性添加到信号事件定义中:
<signal id="alertSignal" name="alert" flowable:scope="processInstance"/>
此属性的默认值为*“global”*。
信号事件示例
以下是使用信号进行通信的两个独立进程的示例。如果更新或更改保险单,则启动第一个流程。在人类参与者审查了更改后,将抛出信号事件,表明策略已更改:
现在,所有感兴趣的流程实例都可以捕获此事件。以下是订阅该事件的流程示例。
注意:了解信号事件向所有活动处理程序广播非常重要。这意味着,在上面给出的示例的情况下,捕获信号的过程的所有实例将接收事件。在这种情况下,这就是我们想要的。但是,也存在无意中广播行为的情况。请考虑以下过程:
BPMN不支持上述过程中描述的模式。这个想法是,执行“执行某事”任务时抛出的错误被边界错误事件捕获,使用信号throw事件传播到并行执行路径,然后中断“并行执行”任务。到目前为止,Flowable将按预期执行。信号将传播到捕获边界事件并中断任务。**但是,由于信号的广播语义,它还将传播到已订阅信号事件的所有其他进程实例。**在这种情况下,这可能不是我们想要的。
注意: signal事件不会对特定流程实例执行任何类型的关联。相反,它会广播到所有流程实例。如果只需要向特定流程实例发送信号,请手动执行关联并signalEventReceived(String signalName, String executionId)
与相应的查询机制一起使用。
Flowable确实有办法通过将scope属性添加到设置为processInstance的signal事件来解决此问题。
1.1.5 消息事件定义
消息事件是引用命名消息的事件。消息具有名称和有效负载。与信号不同,消息事件始终指向单个接收器。
使用该messageEventDefinition
元素声明消息事件定义。该属性messageRef
引用message
声明为definitions
根元素的子元素的元素。以下是一个过程的摘录,其中两个消息事件由start事件和中间捕获消息事件声明和引用。
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:flowable="http://flowable.org/bpmn"
targetNamespace="Examples"
xmlns:tns="Examples">
<message id="newInvoice" name="newInvoiceMessage" />
<message id="payment" name="paymentMessage" />
<process id="invoiceProcess">
<startEvent id="messageStart" >
<messageEventDefinition messageRef="newInvoice" />
</startEvent>
...
<intermediateCatchEvent id="paymentEvt" >
<messageEventDefinition messageRef="payment" />
</intermediateCatchEvent>
...
</process>
</definitions>
抛出一个消息事件
作为可嵌入的流程引擎,Flowable并不关心实际接收消息。这将取决于环境并且需要特定于平台的活动,例如连接到JMS(Java消息服务)队列/主题或处理Web服务或REST请求。因此,接收消息是您必须实现的过程引擎嵌入的应用程序或基础结构的一部分。
在应用程序中收到消息后,您必须决定如何处理它。如果消息应触发新流程实例的启动,请在运行时服务提供的以下方法之间进行选择:
ProcessInstance startProcessInstanceByMessage(String messageName);
ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);
ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey,
Map<String, Object> processVariables);
这些方法使用引用的消息启动流程实例。
如果消息需要由现有流程实例接收,则首先必须将消息关联到特定流程实例(请参阅下一节),然后触发等待执行的继续。运行时服务提供以下方法,用于根据消息事件订阅触发执行:
void messageEventReceived(String messageName, String executionId);
void messageEventReceived(String messageName, String executionId, HashMap<String, Object> processVariables);
查询消息事件订阅
- 在消息启动事件的情况下,消息事件订阅与特定的流程定义相关联。可以使用以下命令查询此类消息订阅
ProcessDefinitionQuery
:
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.messageEventSubscription("newCallCenterBooking")
.singleResult();
由于特定邮件订阅只能有一个流程定义,因此查询始终返回零或一个结果。如果更新了流程定义,则只有最新版本的流程定义才能订阅消息事件。
- 在中间捕获消息事件的情况下,消息事件订阅与特定执行相关联。可以使用以下命令查询此类消息事件订阅
ExecutionQuery
:
Execution execution = runtimeService.createExecutionQuery()
.messageEventSubscriptionName("paymentReceived")
.variableValueEquals("orderId", message.getOrderId())
.singleResult();
此类查询称为相关查询,通常需要有关进程的知识(在这种情况下,给定orderId最多只有一个流程实例)。
消息事件示例
以下是可以使用两个不同消息启动的进程示例:
如果流程需要替代方法来响应不同的启动事件,但最终以统一的方式继续,这将非常有用。
1.1.6 开始活动
开始事件表示进程的开始位置。类型开始事件(处理开始于消息的到达,在特定的时间间隔,等等),定义如何在处理开始时,被示出为在事件的视觉表示一个小图标。在XML表示中,类型由子元素的声明给出。
开始事件总是捕获:从概念上讲,事件(在任何时候)等待直到某个触发发生。
在start事件中,可以指定以下Flowable特定属性:
- initiator:标识进程启动时将在其中存储经过身份验证的用户ID的变量名称。例如:
<startEvent id="request" flowable:initiator="initiator" />
必须使用IdentityService.setAuthenticatedUserId(String)
try-finally块中的方法设置经过身份验证的用户,如下所示:
try {
identityService.setAuthenticatedUserId("bono");
runtimeService.startProcessInstanceByKey("someProcessKey");
} finally {
identityService.setAuthenticatedUserId(null);
}
此代码已粘贴到Flowable应用程序中,因此它与Forms结合使用。
1.1.7 无开始活动
描述
一个没有启动事件技术上意味着启动过程的实例的触发是不确定的。这意味着引擎无法预测何时必须启动流程实例。通过调用startProcessInstanceByXXX方法之一,通过API启动流程实例时,将使用none start事件。
ProcessInstance processInstance = runtimeService.startProcessInstanceByXXX();
*注意:*子进程始终具有无启动事件。
图形符号
无启动事件可视化为没有内部图标的圆圈(换句话说,没有触发类型)。
XML表示
无启动事件的XML表示是没有任何子元素的正常启动事件声明(其他启动事件类型都具有声明该类型的子元素)。
<startEvent id="start" name="my start event" />
无启动事件的自定义扩展
formKey:引用用户在启动新流程实例时必须填写的表单定义。更多信息可以在表单部分找到示例:
<startEvent id="request" flowable:formKey="request" />
1.1.8 定时器启动事件
描述
计时器启动事件用于在给定时间创建流程实例。它既可以用于应该只启动一次的进程,也可以用于应该以特定时间间隔启动的进程。
*注意:*子进程不能有计时器启动事件。
*注意:*一旦部署了进程,就会安排启动计时器事件。不需要调用startProcessInstanceByXXX,虽然调用start process方法不受限制,并且会在startProcessInstanceByXXX调用时再引发一个进程。
*注意:*当部署具有启动计时器事件的新版本的进程时,将删除与先前计时器对应的作业。原因是通常不希望自动启动旧版本流程的新流程实例。
图形符号
计时器启动事件可视化为带有时钟内部图标的圆圈。
XML表示
计时器启动事件的XML表示是具有计时器定义子元素的正常启动事件声明。有关配置详细信息,请参阅计时器定义。
示例:从2011年3月11日12:13开始,过程将以5分钟为间隔开始4次
<startEvent id="theStart">
<timerEventDefinition>
<timeCycle>R4/2011-03-11T12:13/PT5M</timeCycle>
</timerEventDefinition>
</startEvent>
示例:进程将在所选日期开始一次
<startEvent id="theStart">
<timerEventDefinition>
<timeDate>2011-03-11T12:13:14</timeDate>
</timerEventDefinition>
</startEvent>
1.1.9 消息开始事件
描述
一个消息开始事件可用于使用已命名的信息来启动一个过程实例。这有效地允许我们使用消息名称从一组备选启动事件中选择正确的启动事件。
在使用一个或多个消息启动事件部署流程定义时,以下注意事项适用:
- 消息启动事件的名称在给定的流程定义中必须是唯一的。流程定义不能具有多个具有相同名称的消息启动事件。Flowable在部署包含两个或多个引用相同消息的消息启动事件的流程定义时抛出异常,或者两个或多个消息启动事件引用具有相同消息名称的消息时抛出异常。
- 消息启动事件的名称在所有已部署的流程定义中必须是唯一的。Flowable在部署包含一个或多个消息启动事件的流程定义时抛出异常,该消息启动事件引用与已由不同流程定义部署的消息启动事件同名的消息。
- 流程版本控制:部署新版本的流程定义后,将删除先前版本的启动消息订阅。
当启动一个流程实例,可以使用在下面的方法来触发的消息开始的事件RuntimeService
:
ProcessInstance startProcessInstanceByMessage(String messageName);
ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);
ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey,
Map<String, Object< processVariables);
的messageName
是在给定的名字name
的属性message
由引用元素messageRef
的属性messageEventDefinition
。启动流程实例时,以下注意事项适用:
- 消息启动事件仅在顶级进程上受支持。嵌入式子进程不支持消息启动事件。
- 如果流程定义具有多个消息启动事件,则
runtimeService.startProcessInstanceByMessage(…)
允许选择适当的启动事件。 - 如果一个流程定义有多个消息开始的事件和一个没有启动的事件,
runtimeService.startProcessInstanceByKey(…)
或者runtimeService.startProcessInstanceById(…)
使用无启动事件启动流程实例。 - 如果一个流程定义有多个消息开始的事件,并没有没有启动事件,
runtimeService.startProcessInstanceByKey(…)
或者runtimeService.startProcessInstanceById(…)
抛出一个异常。 - 如果一个流程的定义有一个消息开始的事件,
runtimeService.startProcessInstanceByKey(…)
或者runtimeService.startProcessInstanceById(…)
使用消息开始的事件开始一个新的流程实例。 - 如果从引用活动启动进程,则仅支持消息启动事件
- 除了消息启动事件之外,该进程还有一个无启动事件
- 该进程有一个消息启动事件,没有其他启动事件。
图形符号
消息开始事件可视化为带有消息事件符号的圆圈。符号未填充,表示捕获(接收)行为。
XML表示
消息启动事件的XML表示是带有messageEventDefinition子元素的正常启动事件声明:
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:flowable="http://flowable.org/bpmn"
targetNamespace="Examples"
xmlns:tns="Examples">
<message id="newInvoice" name="newInvoiceMessage" />
<process id="invoiceProcess">
<startEvent id="messageStart" >
<messageEventDefinition messageRef="tns:newInvoice" />
</startEvent>
...
</process>
</definitions>
1.1.10 信号启动事件
描述
一个信号启动事件可用于使用命名信号来启动一个过程实例。可以使用中间信号throw事件或通过API(runtimeService.signalEventReceivedXXX方法)从流程实例中触发信号。在这两种情况下,将启动具有相同名称的信号启动事件的所有流程定义。
请注意,在这两种情况下,还可以在流程实例的同步和异步启动之间进行选择。
在signalName
必须在API中传递是在给定的名称name
的属性signal
被引用的元素signalRef
的属性signalEventDefinition
。
图形符号
信号开始事件可视化为具有信号事件符号的圆圈。符号未填充,表示捕获(接收)行为。
XML表示
信号启动事件的XML表示是具有signalEventDefinition子元素的正常启动事件声明:
<signal id="theSignal" name="The Signal" />
<process id="processWithSignalStart1">
<startEvent id="theStart">
<signalEventDefinition id="theSignalEventDefinition" signalRef="theSignal" />
</startEvent>
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />
<userTask id="theTask" name="Task in process A" />
<sequenceFlow id="flow2" sourceRef="theTask" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
1.1.11 错误开始事件
描述
一个错误启动事件可用于触发事件的子过程。错误启动事件不能用于启动流程实例。
错误启动事件总是在中断。
图形符号
错误开始事件可视化为带有错误事件符号的圆圈。符号未填充,表示捕获(接收)行为。
XML表示
错误启动事件的XML表示形式是带有errorEventDefinition子元素的正常启动事件声明:
<startEvent id="messageStart" >
<errorEventDefinition errorRef="someError" />
</startEvent>
1.1.12 结束事件
结束事件表示流程或子流程中路径的结束。终结事件总是在抛出。这意味着当流程执行到达结束事件时,将抛出结果。结果的类型由事件的内部黑色图标描绘。在XML表示中,类型由子元素的声明给出。
1.1.13 无结束事件
描述
一个没有终点事件意味着结果当达到该事件是不确定的抛出。因此,除了结束当前的执行路径之外,引擎不会做任何额外的事情。
图形符号
无端事件可视化为具有粗边框但没有内部图标(无结果类型)的圆。
XML表示
无结束事件的XML表示是正常的结束事件声明,没有任何子元素(其他结束事件类型都有一个声明该类型的子元素)。
<endEvent id="end" name="my end event" />
1.1.14 错误结束事件
描述
当流程执行到达错误结束事件时,当前执行路径结束并抛出错误。匹配的中间边界错误事件可能会捕获此错误。如果未找到匹配的边界错误事件,则将引发异常。
图形符号
错误结束事件可视化为典型的结束事件(具有粗边框的圆圈),其中包含错误图标。错误图标完全是黑色,表示其抛出语义。
XML表示
错误结束事件表示为结束事件,带有errorEventDefinition子元素。
<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="myError" />
</endEvent>
所述errorRef属性可以引用错误指在过程之外定义元件:
<error id="myError" errorCode="123" />
...
<process id="myProcess">
...
该的errorCode的的错误将用于查找匹配的捕捉边界错误事件。如果errorRef与任何已定义的错误不匹配,则errorRef将用作errorCode的快捷方式。这是一个Flowable特定的快捷方式。更具体地说,以下片段在功能上是等同的。
<error id="myError" errorCode="error123" />
...
<process id="myProcess">
...
<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="myError" />
</endEvent>
...
相当于
<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="error123" />
</endEvent>
请注意,errorRef必须符合BPMN 2.0模式,并且必须是有效的QName。
1.1.5 终止结束事件
描述
当达到终止结束事件时,将终止当前流程实例或子流程。从概念上讲,当执行到达终止结束事件时,将确定并结束第一范围(流程或子流程)。请注意,在BPMN 2.0中,子流程可以是嵌入式子流程,调用活动,事件子流程或事务子流程。此规则通常适用:例如,当存在多实例调用活动或嵌入式子流程时,仅该实例将结束,其他实例和流程实例不受影响。
可以添加可选属性terminateAll。如果为true,则无论在流程定义中是否放置终止结束事件,并且无论是否处于子流程(甚至是嵌套),(根)流程实例都将终止。
图形符号
取消结束事件可视化为典型的结束事件(具有粗轮廓的圆圈),内部带有完整的黑色圆圈。
XML表示
终止事件事件表示为end事件,具有terminateEventDefinition子元素。
请注意,terminateAll属性是可选的(默认情况下为false)。
<endEvent id="myEndEvent >
<terminateEventDefinition flowable:terminateAll="true"></terminateEventDefinition>
</endEvent>
1.1.16 取消结束事件
描述
取消结束事件只能与BPMN事务子流程结合使用。当到达取消结束事件时,抛出取消事件,必须由取消边界事件捕获。取消边界事件然后取消交易并触发补偿。
图形符号
取消结束事件可视化为典型的结束事件(具有粗轮廓的圆圈),其中包含取消图标。取消图标完全是黑色,表示其抛出语义。
XML表示
取消结束事件表示为结束事件,具有cancelEventDefinition子元素。
<endEvent id="myCancelEndEvent">
<cancelEventDefinition />
</endEvent>
1.1.17 边界事件
边界事件捕获附加到活动的事件(边界事件永远不会抛出)。这意味着当活动正在运行时,事件正在侦听某种类型的触发器。捕获事件时,活动将中断,并且将遵循从事件中退出的序列流。
所有边界事件都以相同的方式定义:
<boundaryEvent id="myBoundaryEvent" attachedToRef="theActivity">
<XXXEventDefinition/>
</boundaryEvent>
边界事件定义为
- 唯一标识符(流程范围内)
- 通过attachedToRef属性引用事件的活动的引用。请注意,边界事件的定义与它们所附加的活动处于同一级别(换句话说,在活动中不包含边界事件)。
- 形式为XXXEventDefinition的XML子元素(例如,TimerEventDefinition,ErrorEventDefinition等),用于定义边界事件的类型。有关详细信息,请参阅特定边界事件类型。
1.1.18 定时器边界事件
描述
计时器边界事件充当秒表和闹钟。当执行到达附加边界事件的活动时,启动计时器。当计时器触发时(例如,在指定的间隔之后),活动被中断并且遵循边界事件之外的顺序流。
图形符号
计时器边界事件可视化为典型的边界事件(边界上的圆圈),内部有计时器图标。
XML表示
计时器边界事件被定义为常规边界事件。在这种情况下,特定类型的子元素是timerEventDefinition元素。
<boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport">
<timerEventDefinition>
<timeDuration>PT4H</timeDuration>
</timerEventDefinition>
</boundaryEvent>
有关定时器配置的详细信息,请参阅定时器事件定义。
在图形表示中,圆圈的线条点缀,如上例所示:
典型的用例是在一段时间后发送升级电子邮件,但不会影响正常的流程。
中断和非中断定时器事件之间存在关键差异。不间断意味着原始活动不会中断但保持原样。中断行为是默认行为。在XML表示中,cancelActivity属性设置为false:
<boundaryEvent id="escalationTimer" cancelActivity="false" attachedToRef="firstLineSupport"/>
**注:**边界计时器事件仅当启用了异步执行发生(asyncExecutorActivate需要被设置为true
在flowable.cfg.xml
,因为异步执行默认情况下禁用)。
边界事件的已知问题
在使用任何类型的边界事件时,存在关于并发性的已知问题。目前,不可能将多个传出序列流附加到边界事件。该问题的解决方案是使用一个传递到并行网关的传出序列流。
1.1.19 错误边界事件
描述
活动边界上的中间捕获错误或简称边界错误事件捕获在定义它的活动范围内引发的错误。
定义边界错误事件对嵌入式子流程或调用活动最有意义,因为子流程为子流程内的所有活动创建范围。错误结束事件引发错误。这样的错误将向上传播其父作用域,直到找到定义了与错误事件定义匹配的边界错误事件的作用域。
捕获错误事件时,将销毁定义边界事件的活动,同时销毁(并发活动,嵌套子流程等)中的所有当前执行。在边界事件的输出序列流之后继续执行流程。
图形符号
边界错误事件可视化为边界上的典型中间事件(内部具有较小圆圈的圆圈),其中包含错误图标。错误图标为白色,表示其捕获语义。
XML表示
边界错误事件被定义为典型的边界事件:
<boundaryEvent id="catchError" attachedToRef="mySubProcess">
<errorEventDefinition errorRef="myError"/>
</boundaryEvent>
与错误结束事件一样,errorRef引用在process元素外部定义的错误:
<error id="myError" errorCode="123" />
...
<process id="myProcess">
...
该的errorCode用来匹配被发现的错误:
- 如果errorRef被省略,边界错误事件将捕获任何错误事件,而不管errorCode的错误。
- 如果提供了errorRef并且它引用了现有错误,则边界事件将仅捕获具有相同错误代码的错误。
- 如果提供了errorRef,但BPMN 2.0文件中没有定义错误,则errorRef用作errorCode(类似于错误结束事件)。
例
以下示例流程显示了如何使用错误结束事件。当通过没有提供足够的信息来完成*“审查盈利能力”用户任务时,会引发错误。如果在子流程的边界上发现此错误,则“审核销售线索”子流程中的所有活动活动都将被销毁(即使“审核客户评级”尚未完成),并且“提供其他详细信息” '*用户任务已创建。
此过程在演示设置中作为示例提供。可以在org.flowable.examples.bpmn.event.error包中找到进程XML和单元测试。
1.1.20 信号边界事件
描述
在活动边界上的附加中间捕获 信号或简称边界信号事件捕获具有与参考信号定义相同的信号名称的信号。
**注意:**与其他事件(例如边界错误事件)相反,边界信号事件不仅捕获从其附加的范围抛出的信号事件。相反,信号事件具有全局范围(广播语义),这意味着信号可以从任何地方抛出,甚至可以从不同的流程实例抛出。
**注意:**与其他事件(例如错误事件)相反,如果捕获了信号,则不会消耗该信号。如果有两个活动信号边界事件捕获相同的信号事件,则两个边界事件都会被触发,即使它们是不同流程实例的一部分。
图形符号
边界信号事件可视化为边界上的典型中间事件(内部具有较小圆的圆),其中具有信号图标。信号图标为白色(未填充),表示其捕获语义。
XML表示
边界信号事件被定义为典型的边界事件:
<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true">
<signalEventDefinition signalRef="alertSignal"/>
</boundaryEvent>
例
请参阅有关信号事件定义的部分。
1.1.21 消息边界事件
描述
在活动边界上附加的中间捕获 消息或简称边界消息事件捕获具有与引用的消息定义相同的消息名称的消息。
图形符号
边界消息事件可视化为边界上的典型中间事件(内部具有较小圆圈的圆圈),其中包含消息图标。消息图标为白色(未填充),以指示其捕获语义。
请注意,边界消息事件可以是中断(右侧)和非中断(左侧)。
XML表示
边界消息事件被定义为典型的边界事件:
<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true">
<messageEventDefinition messageRef="newCustomerMessage"/>
</boundaryEvent>
例
请参阅有关消息事件定义的部分。
1.1.22 取消边界事件
描述
当事务被取消时,触发事务子流程边界或简称边界取消事件的附加中间捕获取消事件。触发取消边界事件时,它首先中断当前作用域中的所有活动执行。接下来,它开始补偿交易范围内的所有有效补偿边界事件。补偿是同步进行的,换句话说,边界事件在离开交易之前等待补偿之前等待。当补偿完成时,使用在取消边界事件之外的任何序列流来保留事务子过程。
**注意:**事务子流程只允许一个取消边界事件。
**注意:**如果事务子流程承载嵌套的子流程,则仅对已成功完成的子流程触发补偿。
**注意:**如果在具有多实例特征的事务子流程上放置取消边界事件,则如果一个实例触发取消,则边界事件将取消所有实例。
图形符号
取消边界事件可视化为边界上的典型中间事件(内部具有较小圆圈的圆圈),其中具有取消图标。取消图标为白色(未填充),表示其捕获语义。
XML表示
取消边界事件被定义为典型的边界事件:
<boundaryEvent id="boundary" attachedToRef="transaction" >
<cancelEventDefinition />
</boundaryEvent>
由于取消边界事件始终在中断,因此cancelActivity
不需要该属性。
1.1.23 补偿边界事件
描述
附加的中间捕获的活动或边界上的补偿补偿边界事件对于短的,可以被用来补偿处理程序附加到活动。
补偿边界事件必须使用定向关联引用单个补偿处理程序。
补偿边界事件与其他边界事件具有不同的激活策略。其他边界事件(例如信号边界事件)在启动它们所附加的活动时被激活。活动结束后,将停用它们并取消相应的事件订阅。补偿边界事件是不同的。补偿边界事件在附加的活动成功完成时激活。此时,创建对补偿事件的相应订阅。在触发补偿事件或相应的流程实例结束时,将删除订阅。由此可见:
- 触发补偿时,与补偿边界事件关联的补偿处理程序的调用次数与成功完成的活动的次数相同。
- 如果将补偿边界事件附加到具有多个实例特征的活动,则会为每个实例创建补偿事件订阅。
- 如果补偿边界事件附加到循环内包含的活动,则每次执行活动时都会创建补偿事件订阅。
- 如果流程实例结束,则取消对补偿事件的订阅。
**注意:**嵌入式子流程不支持补偿边界事件。
图形符号
补偿边界事件可视化为边界上的典型中间事件(内部具有较小圆的圆),其中具有补偿图标。补偿图标为白色(未填充),表示其捕获语义。除了补偿边界事件之外,下图还显示了使用单向关联与边界事件关联的补偿处理程序:
XML表示
补偿边界事件被定义为典型的边界事件:
<boundaryEvent id="compensateBookHotelEvt" attachedToRef="bookHotel" >
<compensateEventDefinition />
</boundaryEvent>
<association associationDirection="One" id="a1"
sourceRef="compensateBookHotelEvt" targetRef="undoBookHotel" />
<serviceTask id="undoBookHotel" isForCompensation="true" flowable:class="..." />
由于在活动成功完成后激活补偿边界事件,因此cancelActivity
不支持该属性。
1.1.24 中间捕获事件
所有中间捕获事件都以相同的方式定义:
<intermediateCatchEvent id="myIntermediateCatchEvent" >
<XXXEventDefinition/>
</intermediateCatchEvent>
中间捕获事件定义为:
- 唯一标识符(流程范围内)
- 形式为XXXEventDefinition的XML子元素(例如,TimerEventDefinition),用于定义中间捕获事件的类型。有关详细信息,请参阅特定捕获事件类型。
1.1.25 定时器中间捕捉事件
描述
计时器中间事件充当秒表。当执行到达捕获事件活动时,启动计时器。当计时器触发时(例如,在指定的间隔之后),遵循从计时器中间事件发出的顺序流。
图形符号
计时器中间事件可视化为中间捕获事件,内部有计时器图标。
XML表示
计时器中间事件被定义为中间捕获事件。在这种情况下,特定类型子元素是timerEventDefinition元素。
<intermediateCatchEvent id="timer">
<timerEventDefinition>
<timeDuration>PT5M</timeDuration>
</timerEventDefinition>
</intermediateCatchEvent>
请参阅计时器事件定义以获取配置详
1.1.26 信号中间捕捉事件
描述
中间捕获 信号事件捕获具有与参考信号定义相同的信号名称的信号。
**注意:**与其他事件(例如错误事件)相反,如果捕获了信号,则不会消耗该信号。如果有两个活动信号边界事件捕获相同的信号事件,则两个边界事件都会被触发,即使它们是不同流程实例的一部分。
图形符号
中间信号捕获事件可视化为典型的中间事件(内部具有较小圆圈的圆圈),其中具有信号图标。信号图标为白色(未填充),表示其捕获语义。