BPMN2.0 Specifaction 节选翻译,10.4.6 事件处理(handling Events,原文 275页)

 (注:本文由廖贵宾翻译,email:531622@qq.com,若引用请保留本申明和原链接)

 

10.4.6 事件处理(handling Events,原文 275页)

 

BPMN在流程的执行过程中为事件提供了先进的处理方式(例如捕获一个事件)。甚至在流程中支持用户自定义的事件(例如抛出一个事件)。不管是捕获事件方式还是抛出事件方式以及流程的行为结果都是一种事件处理(Event handling)方式。这里有三种类型的事件处理方式:一种是启动事件用来启动流程;另两种是作为普通流的一部分,要么通过边界事件附加在活动(Activities)上的事件处理,要么通过在子流程中申明各种事件处理句柄来处理的方式。

 

启动事件处理(Handling Start Event)

存在多种方式启动流程。对于单一的启动事件(Start Event),每当事件发生时,处理方法都会先创建一个新的流程实例,再跟着执行接下来的流元素(Sequence Flows)。对于存在多个启动事件时,BPMN 支持按照具体的建模情景来执行。

排他启动(Exclusive start):最常见的情景是流程具有多个备选启动事件(Start Event),通过其中一个启动事件(Start Event)就能启动流程。每次备选启动事件中的一个被激活,就能创建一个新的流程实例。接下来的例子显示两个事件(Event)连接到一个活动(Activity)上,见图 10.97。在运行时,任意一个事件发生,都会创建一个流程实例(Process instance)并激活这个活动。注:含有多个消息定义(Message Event Definitions)的单独一个复合启动事件(Multiple Start Event)可以起到相同的效果。

 

一个流程也能通过事件网关(Event-Based Gateway)来创建,如图10.98所示。

 

 

这种情况下,按照基于事件的排他网关(Event-Based Exclusive Gateway)的语意,第一个匹配的事件会创建一个新的流程实例,并且网关会等待另一个事件。注:这种情景只存在于该网关没有输入流元素情况下。

 

一个流程可以含有多组事件网关(Event-Based Gateways),这些网关被用来参与同一个会话(Conversation),因此会共享相同的关联信息。这种会话的情况下,各组网关之外的事件(Event)需要送到网关中;当第一个事件创建了新的流程实例后,接下来的事件会依据事件中的相关信息(correlation information)来决定路由到具体的流程实例中。

 

事件同步(Event synchronization):如果流程建模者需要几个不相关的启动事件(Start Event)在一个流程实例中合并,那么必须使用下面的表示方法(见图 10.99)。

 

并行的启动事件(Parallel Start Event)可以打包几个一起发生的不相关的启动事件,用来创建并发送到同一个流程实例中。该启动事件跟随的流元素通常也会被执行。

到原文439页,参见启动事件的处理(Event handling of Start Events)执行语意。

 

普通流元素中的事件处理(中间事件)

对于中间事件(Intermediate Events),处理程序一直等待着事件的发生。当中间事件节点被执行时,处理程序就开始等待事件了。一旦事件发生,就会被处理程序处理。该中间事件元素跟随的流元素通常也会被执行。

 

附加在活动节点上的事件处理(中间边界事件和子流程事件)

对于边界事件,处理程序除了执行边界事件指向的离开活动节点的流元素分支外,还需要执行本活动节点的取消操作,或者通过执行事件句柄(Event Handler)来代替执行取消操作。执行事件句柄仅对消息事件(Message),信号事件(Signal),定时器事件(Timer)和条件事件(Conditional Events)有效,不应用于错误事件(Error Events)。

 

当活动(Activity)的 cancelActivity 属性为 true 时,就定义了一个可中断的边界事件。无论什么时候事件发生时,关联的活动就会被中断执行。一个用来激活该流程中例外处理分支(exception flow)的下一个流元素的标记(token)会被生成。(例外处理分支是一个不含有条件分支的流程处理分支。)

 

当活动(Activity)的 cancelActivity 属性为 false 时,就定义了一个不能被打断的边界事件。无论什么时候事件发生时,关联的活动会继续执行。一个用来执行边界事件的与活动并行的处理分支的标记(token)会被生成,必须小心该分支流需要合并进该流程的主干(main flow)中去——典型的做法是合并到该流程的结束节点(End Event)上。

 

下面的例子是一个旅行预订旅店的流程片段(见图 10.100)。该流程的子流程由一个主体部份和三个事件子流程组成。子流程使用相同的运行环境(context)来处理事件:出错事件子流程用来取消子流程,消息事件子流程用来更新子流程的状态从而推进流程,还有一个补偿事件子流程。

 

 

 

下面的例子(见图 10.101)展示了相同功能的预订旅店的流程片段,使用了边界事件代替内部子流程事件。注意,在这个例子中,事件处理程序没有共享“预订”子流程的运行环境(context),因为处理程序是在子程序的外面执行。因此,实际上的补偿逻辑是作为黑盒不公开细节。

 

注意,接下来说明边界事件处理中,中断活动节点执行和不中断活动节点执行之间的区别。对于需要中断的事件(出错事件Error, 升级事件 Escalation,消息事件 Message,信号事件 Signal, 定时器事件 Timer,条件事件 Conditional,复合事件 Multiple 和 并发复合事件 Parallel Multiple),对同一个事件声明(Event Declaration)仅能生成一个事件子流程(Event Sub-Process)。调用事件子流程,就不能调用非中断的事件处理句柄程序。

 

这种限制的原因是由于事件子程序和边界子程序的性质决定的。他们的执行都会立即中断其归属的活动节点的运行。这意味着在同一时间仅有一个事件子流程可以被运行。不过,当每个中断处理句柄归属不同的事件声明(Event Declaration)时,就不限制建模者建立多个中断处理句柄。

 

对于非中断的事件(升级事件 Escalation,消息事件 Message, 信息事件 Signal, 定时器事件 Timer, 条件事件 Conditional, 复合事件 Multiple 和并行复合事件 Parallel Multiple),同一个事件定义并不会限制可以并行的事件子流程的数目。在运行时,它们的调用顺序是无序的。在调用执行非中断的事件子流程时,其父节点的活动的流程要求也能正常执行下去。

 

如果存在一个子流程,同时含有内部事件子流程和边界事件事处理流程,并且使用相同的事件定义(EventDefinition),需按如下规则执行:

  •  如果事件子流程(Event Sub-Process)在执行完成后抛出事件,则会触发边界事件。

 

  •  如果事件子流程(Event Sub-Process)在执行完成后,没有抛出事件,其附属的活动节点(Activity)应该继续完成刚才被中断的程序。换一个说法,这时事件子流程把刚才的事件“吸收”了。

 

中断事件句柄 Interrupting Event Handlers (出错事件 Error, 升级事件 Escalation, 消息事件 Message, 信号事件 Signal, 定时器事件 Timer, 条件事件 Conditional,复合事件 Multiple和 并行复合事件 Parallel Multiple)

中断事件句柄,是那些活动节点的 cancelActivity 属性设为 true 时,收到事件后的程序调用接口。当收到事件后,不管处理事件的流程是子流程还是边界元素,事件关联的活动节点都会被中断执行。如果是使用内部子流程来处理事件,运行环境是与事件关联的活动节点共享的;如果是使用边界元素来捕获出错事件(Error Event),则事件发生后执行边界元素指向的分支流。关联的活动节点都是会执行取消(Cancel)任务的,不管是执行内部出错子流程还是执行边界元素流程。

 

如上面的例子,“预订”子流程内有一个出错句柄(Error handler),在预订出错时会被执行,这时,前面已经预订的内容会被取消,先通过执行booking节点内部的补偿(compensation)来取消,再使用边界元素的出错句柄捕获,执行booking节点外部的流程。

 

非中断的事件句柄 Non-interrupting Event Handlers(出错事件 Error, 升级事件 Escalation, 消息事件 Message, 信号事件 Signal, 定时器事件 Timer, 条件事件 Conditional,复合事件 Multiple和 并行复合事件 Parallel Multiple)

非中断的事件句柄,是那些活动节点属性 cancelActivity 值为 false 时的中断处理程序入口。

 

对于事件子流程(Event Sub-Processes),不论什么时候只要事件发生,就执行关联的事件子流程。如果并行发生了多个事件,就会通过创建多个事件子流程实例的方式,并行运行多个处理程序。非中断的启动事件,意味着事件子流程实例与子流程是同时并行运行的。

 

对于边界事件(boundary Events),不论什么时候只要事件发生,就会与活动的主流程并行运行。如果同时存在一个事件子流程与边界事件处理相同的事件,先执行子流程,然后再执行边界事件。这个与活动节点处理流并行的边界事件流,必须与主处理流(活动节点处理流)进行合并——典型的合并方法是连接到本流程的结束事件(End Event)上。

 

如上例所示,在“预订”子流程中,事件处理句柄允许信用卡的信息更新。通过含有信用卡信息的消息事件(Message)进行处理:这个消息事件无论什么时候都能被子流程的主体内的控制流接收并处理。一旦这个消息事件被接收到,活动节点内的响应事件名柄就会与活动内的子流程同步并行执行。

 

参见原文440页的“Intermediate Events“部分,查寻精确的边界上的中间事件(Intermediate Events)的语义,和原文440页的”Event Sub-Process“部分,查寻非中断事件子程序的语义。

 

结束事件处理 Handling End Events

对于终止结束事件(Terminate End Event)的处理,是终止流程中所有的活动节点。

取消结束事件(Cancel End Event)仅在事务子流程(Transaction Sub-Process)内被允许出现。例如,在事务子流程中取消子流程的执行。

 

对所有其它的结束事件(End Event),执行事件定义(EventDefinition)中指定的行为程序。当流程或子流程实例中没有更多激活的活动节点时,实例就处于结束(completed)了。见原文 443页,查寻精确语义。

 

10.4.7 范围特性 Scopes

范围特性是用来描述流程中活动节点的运行程序的上下文(context)。它由以下部分组成:

  • 可访问的数据Data Objects(包括数据的输入输出)
  • 可访问的事件,包括抛出事件和捕获事件
  • 范围内可发生的对话Conversations

 

一般当流程启动后,流程中的活动元素节点在被运行时,节点实例中都会有一个范围特性(scope)来为节点内的子流程流转提供运行环境。同样的,这里的每个活动元素节点也被包含在另一个范围特性(scope)中。所以,范围特性(scope)是层层嵌套的。

 

一个范围特性(scope)在运行时,能生成多个范围实例。它们也是按照其创建方式进行层层嵌套的。在一个范围实例中能激活多个标记(tokens)。

 

范围实例是有生命周期的,具有如下状态:

  •  Activated 被激活的
  •  In execution 在运行中
  •  Completed 已完成
  •  In Compensation 在补偿处理中
  •  Compensation 补偿
  •  In Error 出错处理中
  •  In Cancellation 取消处理中
  •  Cancelled 已取消

 

BPMN 元素中,具有范围特性的元素:

  •  Choreography 流程编排
  •  Pool 泳池
  •  Sub-Process 子流程
  •  Task 任务
  •  Activity 活动
  •  Multi-instances body多实例

 

范围特性(Scopes)定义的语义:

  •  数据元素的可见性(包括数据输入和输出)
  •  事件的解析
  •  开启或停止标记(token)的执行

 

数据元素(Data Object),事件(Event)和通过范围特性(scope)描述的关联(correlation keys),能被明确的建模或遵守默认定义。

 

原文地址:https://www.cnblogs.com/citycomputing/p/14386673.html