(二)BPMN2.0规范介绍——2事件 Events

目录

一、事件定义

1. 定时器事件定义 Timer Event Definitions

(1)定义

(2)timeDate

(3)timeDuration

 (4)timeCycle

(5)ISO 8601标准定义

2. 消息事件定义 Message Event Definitions

3. 信号事件定义 Signal Event Definitions

(1)定义

(2)抛出信号事件 Throwing a Signal Event

(3)捕获信号事件 Catching a Signal Event

(4)查询信号事件订阅 Querying for Signal Event subscriptions

(5)信号事件范围 Signal event scope

(6)信号事件示例 Signal Event example(s)

4. 错误事件定义 Error Event Definitions

二、启动事件

1. 空启动事件 None Start Event

2. 定时器启动事件 Timer Start Event

3.消息启动事件 Message Start Event

4. 信号启动事件 Signal Start Event

5. 错误启动事件 Error Start Event

三、结束事件

1. 描述

2. 空结束事件 None End Event

3. 错误结束事件 Error End Event

4. 终止结束事件 Terminate End Event

5. 取消结束事件 Cancel End Event

四、边界事件 Boundary Events

1. 定时器边界事件 Timer Boundary Event

2. 错误边界事件 Error Boundary Event

3. 信号边界事件 Signal Boundary Event

4. 消息边界事件 Message Boundary Event

5. 取消边界事件 Cancel Boundary Even

6. 补偿边界事件 Compensation Boundary Event

五、 捕获中间事件 Intermediate Catching Events

1. 定时器捕获中间事件 Timer Intermediate Catching Event

2. 信号捕获中间事件 Signal Intermediate Catching Event

3. 消息捕获中间事件 Message Intermediate Catching Event

六、抛出中间事件 Intermediate Throwing Event

1. 空抛出中间事件 Intermediate Throwing None Event

2. 信号抛出中间事件 Signal Intermediate Throwing Event

3. 补偿抛出中间事件 Compensation Intermediate Throwing Event


一、事件定义

事件通常用于为流程生命周期中发生的事情建模。事件总是图形化为圆圈。在BPMN 2.0中,有两种主要的事件分类:捕获(catching)与抛出(throwing)事件。

  • 捕获(catching):

当流程执行到达这个事件时,会等待直到触发器动作。触发器的类型,由其中的图标,或者说XML中的类型声明而定义。捕获事件与抛出事件显示上的区别,是其内部的图标没有填充(也就是说,是白色的)。

  • 抛出(throwing):

当流程执行到达这个事件时,会触发一个触发器。触发器的类型,由其中的图标,或者说XML中的类型声明而定义。抛出事件与捕获事件显示上的区别,是其内部的图标填充为黑色。

 

1. 定时器事件定义 Timer Event Definitions

(1)定义

定时器事件,是由定义的定时器触发的事件。可以用于开始事件 start event中间事件 intermediate event,或边界事件 boundaryevent。定时器事件的行为,取决于所使用的业务日历(business calendar)。定时器事件有默认的业务日历,但也可以为每个定时器事件定义,定义业务日历。

<timerEventDefinition activiti:businessCalendarName="custom">
...
</timerEventDefinition>

其中businessCalendarName指向流程引擎配置中的业务日历。如果省略业务日历定义,就使用默认业务日历。

定时器定义必须且只能使用下列的一种元素

(2)timeDate
 

这个方式指定了ISO 8601格式的固定时间。 在这个时间点,会触发触发器。例如:
<timerEventDefinition>
<timeDate>2011‐03‐11T12:13:14</timeDate>
</timerEventDefinition>

(3)timeDuration

要定义在触发前,定时器需要等待多长时间,可以用timeDuration作为timerEventDefinition的子元素来指定。使用ISO 8601格式(BPMN 2.0规范要求)。例如(等待10天):

<timerEventDefinition>
<timeDuration>P10D</timeDuration>
</timerEventDefinition>

 (4)timeCycle

指定重复周期,可用于周期性启动流程,或者为超期用户任务多次发送提醒。这个元素可以使用两种格式。第一种是按照ISO 8601标准定义的循环时间周期。例如(三次重复间隔,每次间隔为10小时):

<timerEventDefinition>
<timeCycle activiti:endDate="2015‐02‐25T16:42:11+00:00">R3/PT10H</timeCycle>
</timerEventDefinition>

也可以指定endDate,作为timeCycle的可选属性,或者像这样直接写在时间表达式的结尾: R3/PT10H/${EndDate} 。 当到达endDate时,应用会停止,并为该任务创建其他作业。 可以使用ISO 8601标准的静态值,比如"2015­02­25T16:42:11+00:00"。也可以使用变量${EndDate}
 

<timerEventDefinition>
<timeCycle>R3/PT10H/${EndDate}</timeCycle>
</timerEventDefinition>

如果同时使用了两种指定方式,则系统会使用属性方式定义的endDate。
目前只有BoundaryTimerEvents与CatchTimerEvent支持EndDate功能。
另外,也可以使用cron表达式指定定时周期。下面的例子展示了一个整点启动,每5分钟触发的触发器:
 

0 0/5 * * * ?

cron表达式使用规则自行百度

重复时间周期更适用于使用相对时间,也就是从某个特定时间点开始计算(比如用户任务开始的时间)。而cron表达式可以使用绝对时间,因此绝对适合用于定时启动事件 timer start events。
可以在定时事件定义中使用表达式,也就是使用流程变量调整定时器定义。这个流程变量必须是包含合适时间格式的字符串,ISO8601(或者对于循环类型,cron)。

<boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport">
<timerEventDefinition>
<timeDuration>${duration}</timeDuration>
</timerEventDefinition>
</boundaryEvent>

 

请注意:定时器只有在作业或者异步执行器启用时才能触发(也就是说,需要在 activiti.cfg.xml 中,将jobExecutorActivate或者asyncExecutorActivate设置为 true 。因为默认情况下,作业与异步执行器都是禁用的)。

 

(5)ISO 8601标准定义

 

格式解析
R2/2015-06-04T19:25:16.828696-07:00/P1DT10S

上面的字符串通过"/"分为了三部分即:

重复次数/开始时间/运行间隔

重复次数
R - 将永远重复
R1 - 将重复一次
R231 - 将重复231次。
开始时间
任务第一次运行的时间。如果开始日期时间已经过去,Kala将返回一个错误。

其中"T"用来分割日期和时间,时间后面跟着的"-07:00"表示西七区,注意"-"是连字符,不是减号。

时区默认是0时区,可以用"Z"表示,也可以不写。

对于我国,要使用"+08:00",表示东八区。
上面的字符串表示 2015年6月4日,19点25分16秒828696纳秒,西七区。

运行间隔
运行间隔以"P"开始,和上面一样也是用"T"分割日期和时间,如P1Y2M10DT2H30M15S

P 开始标记
1Y - 一年
2M - 两个月
10D - 十天
T - 时间和日期分的割标记
2H - 两个小时
30M - 三十分钟
15S 十五秒钟
例子,注意如果没有年月日,"T"也不能省略

P1DT1M - 一天一分钟执行一次
P1W - 一周执行一次
PT1H - 一小时执行一次
PT10S - 十秒执行一次

 

2. 消息事件定义 Message Event Definitions

消息事件,是指引用具名消息的事件。消息具有名字与载荷。与信号不同,消息事件只有一个接收者。
消息事件定义使用 messageEventDefinition 元素声明。其 messageRef 属性引用一个 message 元素,该 message 元素需要声明为 definitions 根元素的子元素。下面摘录一个流程,声明了两个消息事件,并由开始事件与消息捕获中间事件(intermediate catching message event)引用
 

<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.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>

 

 

3. 信号事件定义 Signal Event Definitions

(1)定义

信号事件,是引用具名信号的事件。信号是全局范围(广播)的事件,并会被传递给所有激活的处理器(等待中的流程实例/捕获信号事件 catching signal events)。
信号事件定义使用 signalEventDefinition 元素声明。其 signalRef 属性引用一个 signal 元素,该 signal 元素需要声明为 definitions 根元素的子元素。下面摘录一个流程,使用中间事件(intermediate event)抛出与捕获信号事件。
 

<definitions... >
    <!‐‐ 声明信号 ‐‐>
    <signal id="alertSignal" name="alert" />
    <process id="catchSignal">
        <intermediateThrowEvent id="throwSignalEvent" name="Alert">
        <!‐‐ 信号事件定义 ‐‐>
            <signalEventDefinition signalRef="alertSignal" />
        </intermediateThrowEvent>
        ...
        <intermediateCatchEvent id="catchSignalEvent" name="On Alert">
        <!‐‐ 信号事件定义 ‐‐>
            <signalEventDefinition signalRef="alertSignal" />
        </intermediateCatchEvent>
        ...
    </process>
</definitions>

两个 signalEventDefinition 引用同一个 signal 元素。

(2)抛出信号事件 Throwing a Signal Event

信号可以由流程实例使用BPMN结构抛出,也可以通过编程方式使用Java API抛出。下面 org.activiti.engine.RuntimeService 中的方法可以用于编程方式抛出信号:
 

RuntimeService.signalEventReceived(String signalName);
RuntimeService.signalEventReceived(String signalName, String executionId);

signalEventReceived(String signalName); 与 signalEventReceived(String signalName, String executionId); 的区别,是前者在全局范围,为所有已订阅处理器抛出信号(广播),而后者只为指定的执行传递信号。


(3)捕获信号事件 Catching a Signal Event
 

信号事件可用信号捕获中间事件(intermediate catch signal event)或者信号边界事件(signal boundary event)捕获。
 

(4)查询信号事件订阅 Querying for Signal Event subscriptions


可以查询订阅了某一信号事件的所有执行:

List<Execution> executions = runtimeService.createExecutionQuery()
.signalEventSubscriptionName("alert")
.list();

可以使用 signalEventReceived(String signalName, String executionId) 方法为这些执行传递这个信号。

(5)信号事件范围 Signal event scope
 

默认情况下,信号事件在流程引擎全局广播。这意味着你可以在一个流程实例中抛出一个信号事件,而不同流程定义的不同流程实例都会响应这个事件。
然而,有时也会希望只在同一个流程实例中响应信号事件。例如在流程实例中使用异步机制,而两个或多个活动彼此互斥的时候。要限制信号事件的范围(scope),在信号事件定义中添加(非BPMN 2.0标准!)scope属性:

<signal id="alertSignal" name="alert" activiti:scope="processInstance"/>

这个属性的默认值为"global(全局)"。


(6)信号事件示例 Signal Event example(s)

下面是一个关于两个不同的流程通过信号通信的例子。第一个流程在保险政策更新或变更时启动。在变更由人工审核之后,会抛出信号事件,指出政策已经发生了变更:

这个事件可以被所有感兴趣的流程实例捕获。下面是一个订阅这个事件的流程的例子。
 

请注意:信号事件与特定的流程实例无关,而是会广播给所有流程实例。如果你需要只为某一特定的流程实例传递信号,则需要使用 signalEventReceived(String signalName, String executionId) 手动建立关联,并使用适当的的查询机制 querymechanisms。
 

 

4. 错误事件定义 Error Event Definitions

重要提示: BPMN错误与Java异常不是一回事。事实上,这两者毫无共同点。BPMN错误事件是建模业务异常(business exceptions)的方式。而Java异常使用它们自己的方式处理。

<endEvent id="myErrorEndEvent">
    <errorEventDefinition errorRef="myError" />
</endEvent>

 

 

 

二、启动事件

 

 

1. 空启动事件 None Start Event

  • 描述:

“空”启动事件,技术上指的是没有特别指定启动流程实例的触发器。这意味着引擎无法预知何时启动流程实例。空启动事件用于流程实例通过调用下列startProcessInstanceByXXX API方法启动的情况。

  • 图标:

  • java代码:
ProcessInstance processInstance = runtimeService.startProcessInstanceByXXX();
  •  xml表示:

空启动事件的XML表示格式,就是普通的启动事件声明,而没有任何子元素(其他种类的启动事件都有子元素,用于声明其类型)

<startEvent id="start" name="my start event" />
  •  自定义扩展:

formKey: 引用表单模板,用户需要在启动新流程实例时填写该表单。可以在表单章节找到更多信息。例如:

<startEvent id="request" activiti:formKey="org/activiti/examples/taskforms/request.form" />
  • 注意事项:

子流程(subprocess)总是有空启动事件。


2. 定时器启动事件 Timer Start Event

 

  • 描述:

定时器启动事件,用于在指定时间创建流程实例。在流程只需要启动一次,或者流程需要在特定的时间间隔重复启动时,都可以使用。

  • 图标:

  • java代码:
ProcessInstance processInstance = runtimeService.startProcessInstanceByXXX();
  •  xml表示:

定时器启动事件的XML表示格式,是普通的启动事件声明,加上定时器定义子元素。请参考定时器定义了解详细配置方法。

示例:流程会启动4次,间隔5分钟,从2011年3月11日,12:13开始
<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)子流程不能有定时器启动事件。
(2)定时器启动事件,在流程部署的同时就开始计时。不需要调用startProcessInstanceByXXX,尽管也不禁止使用启动流程的方法。调用startProcessInstanceByXXX时也会启动流程。
(3)当部署带有定时器启动事件的流程的新版本时,上一版本的定时器作业会被移除。这是因为通常并不希望旧版本的流程仍然自动启动新的流程实例。

 

 

3.消息启动事件 Message Start Event

  • 描述:

消息启动事件,使用具名消息启动流程实例。它让我们可以使用消息名,有效地在一组可选的启动事件中选择正确的启动事件。当部署具有一个或多个消息启动事件的流程定义时,会考虑下列因素:
(1)消息启动事件的名字,在给定流程定义中,必须是唯一的。一个流程定义不得包含多个同名的消息启动事件。如果流程定义中有两个或多个消息启动事件引用 同一个消息,也即两个或多个消息启动事件引用了具有相同消息名字的消息,则Activiti在部署这个流程定义时,会抛出异常。
(2)消息启动事件的名字,在所有已部署的流程定义中,必须是唯一的。如果流程定义中,一个或多个消息启动事件,引用了已经部署的另一流程定义中消息启动事件的消息名,则Activiti在部署这个流程定义时,会抛出异常。
(3)流程版本:在部署流程定义的新版本时,会取消上一版本的消息订阅。即使新版本中并没有这个消息事件,仍然如此(取消上版本的消息订阅)。

  • 图标:

  • java代码:
当启动流程实例时,可以使用下列 RuntimeService 中的方法,触发消息启动事件:
ProcessInstance startProcessInstanceByMessage(String messageName);
ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);
ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map<String, Object<processVariables);

messageName 是由 message 元素的 name 属性决定的名字。 message 元素被 messageEventDefinition 的 messageRef 属性引用。当启动流程实例时,请考虑下列因素
(1)只有顶层流程(top­level process)才支持消息启动事件。嵌入式子流程不支持消息启动事件。
(2)如果一个流程定义中有多个消息启动事件, runtimeService.startProcessInstanceByMessage(…) 允许选择合适的启动事件。
(3)如果一个流程定义中有多个消息启动事件,与一个空启动事件,则 runtimeService.startProcessInstanceByKey(…) 与runtimeService.startProcessInstanceById(…) 会使用空启动事件启动流程实例。

(4)如果一个流程定义中有多个消息启动事件,而没有空启动事件,则 runtimeService.startProcessInstanceByKey(…) 与 runtimeService.startProcessInstanceById(…) 会抛出异常。

(5) 如果一个流程定义中只有一个消息启动事件,则 runtimeService.startProcessInstanceByKey(…) 与 runtimeService.startProcessInstanceById(…) 会使用这个消息启动事件启动新流程实例。

(6)如果流程由调用活动(call activity)启动,则消息启动事件只有在下列情况下才被支持 :

  •           除了消息启动事件,流程还有唯一的空启动事件
  •           或者流程只有唯一的消息启动事件,而没有其他启动事件。

 

  •  xml表示:

消息启动事件的XML表示格式,为普通启动事件声明,加上messageEventDefinition子元素:

<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.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>

 

4. 信号启动事件 Signal Start Event

  • 描述:

信号启动事件,使用具名信号启动流程实例。这个信号可以由流程实例中的信号抛出中间事件(intermediary signal throw event),或者API(runtimeService.signalEventReceivedXXX方法)触发。这些情况下,所有拥有相同名字信号启动事件的流程定义都会被启动。
 

  • 图标:

  • java代码:
RuntimeService.signalEventReceived(String signalName);
RuntimeService.signalEventReceived(String signalName, String executionId);
  •  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>
  • 注意事项:

请注意这些情况下,都可以选择异步还是同步启动流程实例。
需要为API传递的 signalName ,是由 signal 元素的 name 属性决定的名字。 signal 元素被 signalEventDefinition 的 signalRef属性所引用

 

 

5. 错误启动事件 Error Start Event

 

  • 描述:

错误启动事件,可用于触发事件子流程(Event Sub­Process)。错误启动事件不能用于启动流程实例。错误启动事件总是中断。
 

  • 图标:

错误启动事件,用其中有一个错误事件标志的圆圈表示。这个标志并未填充,用以表示捕获(接收)行为

  • java代码:
RuntimeService.signalEventReceived(String signalName);
RuntimeService.signalEventReceived(String signalName, String executionId);
  •  xml表示:

错误启动事件的XML表示格式,为普通启动事件声明,加上errorEventDefinition子元素

<startEvent id="messageStart" >
<errorEventDefinition errorRef="someError" />
</startEvent>
  • 注意事项:

请注意这些情况下,都可以选择异步还是同步启动流程实例。
需要为API传递的 signalName ,是由 signal 元素的 name 属性决定的名字。 signal 元素被 signalEventDefinition 的 signalRef属性所引用

 


三、结束事件


1. 描述

结束事件标志着(子)流程的(分支的)结束。结束事件总是抛出(型)事件。这意味着当流程执行到达结束事件时,会抛出一个结果。结果的类型由事件内部的黑色图标描绘。在XML表示中,类型由子元素声明给出。

 


2. 空结束事件 None End Event

  • 描述:

“空”结束事件,意味着当到达这个事件时,抛出的结果没有特别指定。因此,引擎除了结束当前执行分支之外,不会多做任何事情。

  • 图标:

空结束事件,用其中没有图标(没有结果类型)的粗圆圈表示

  • java代码:

 

  •  xml表示:

空事件的XML表示格式,为普通结束事件声明,没有任何子元素(其它种类的结束事件都有子元素,用于声明其类型)。

<endEvent id="end" name="my end event" />
  • 注意事项:

 

 


3. 错误结束事件 Error End Event

  • 描述:

当流程执行到达错误结束事件时,结束执行的当前分支,并抛出错误。这个错误可以使用匹配的错误边界中间事件 intermediate boundary error event 捕获。如果找不到匹配的错误边界事件,将会抛出异常

  • 图标:

错误结束事件事件,用内部有一个错误图标的标准结束事件(粗圆圈)表示。错误图标是全黑的,代表抛出的含义。

  • java代码:

 

  •  xml表示:

错误结束事件,表示为结束事件,加上errorEventDefinition子元素:

<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="myError" />
</endEvent>

errorRef属性可以引用在流程外定义的error元素:

<error id="myError" errorCode="123" />
...
<process id="myProcess">
...

error的errorCode用于查找匹配的错误捕获边界事件。如果errorRef不匹配任何已定义的error,则该errorRef会用做errorCode的快捷方式。这个快捷方式是Activiti特有的。下面的代码片段在功能上是相同的

<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概要(schema),且必须是合法的QName。

 


4. 终止结束事件 Terminate End Event

  • 描述:

当到达终止结束事件时,当前的流程实例或子流程会被终止。概念上说,当执行到达终止结束事件时,会判断第一个范围 scope(流程或子流程)并终止它。请注意在BPMN 2.0中,子流程可以是嵌入式子流程,调用活动,事件子流程,或事务子流程。有一条通用规则:当存在多实例的调用过程或嵌入式子流程时,只会终止一个实例,其他的实例与流程实例不会受影响。
可以添加一个可选属性terminateAll。当其为true时,无论该终止结束事件在流程定义中的位置,也无论它是否在子流程(甚至是嵌套子流程)中,都会终止(根)流程实例。

  • 图标:

终止结束事件,用内部有一个全黑圆的标准结束事件(粗圆圈)表示。

  • java代码:

 

  •  xml表示:

终止结束事件,表示为结束事件,加上terminateEventDefinition子元素。
请注意terminateAll属性是可选的(默认为false)。

<endEvent id="myEndEvent >
<terminateEventDefinition activiti:terminateAll="true"></terminateEventDefinition>
</endEvent>
  • 注意事项:

 

 


5. 取消结束事件 Cancel End Event

 

  • 描述:

取消结束事件,只能与bpmn事务子流程(bpmn transaction subprocess)一起使用。当到达取消结束事件时,会抛出取消事件,且必须由取消边界事件(cancel boundary event)捕获。之后这个取消边界事件将取消事务,并触发补偿(compensation)。

  • 图标:

取消结束事件,用内部有一个取消图标的标准结束事件(粗圆圈)表示。取消图标是全黑的,代表抛出的含义。

  • java代码:

 

  •  xml表示:

取消结束事件,表示为结束事件,加上cancelEventDefinition子元素。

<endEvent id="myCancelEndEvent">
<cancelEventDefinition />
</endEvent>
  • 注意事项:

 

 


四、边界事件 Boundary Events

 

边界事件是捕获(型)事件,依附在活动(activity)上(边界事件永远不会抛出)。这意味着当活动运行时,事件在监听特定类型的触发器。当事件捕获时,活动会被终止,并沿该事件的出口顺序流继续。
所有的边界事件都用相同的方式定义:

<boundaryEvent id="myBoundaryEvent" attachedToRef="theActivity">
        <XXXEventDefinition/>
(如: TimerEventDefinition,ErrorEventDefinition,signalEventDefinition,messageEventDefinition)
</boundaryEvent>

边界事件由下列(元素)定义:
(1)唯一标识符(流程范围)
(2)通过attachedToRef属性定义的,对该事件所依附的活动的引用。请注意边界事件,与其所依附的活动,定义在相同级别(也就是说,边界事件并不包含在活动内部)。
(3)定义了边界事件的类型的,XXXEventDefinition形式的XML子元素(例如TimerEventDefinition,ErrorEventDefinition,等等)。查阅特定边界事件类型,以了解更多细节。


1. 定时器边界事件 Timer Boundary Event

  • 描述:

定时器边界事件的行为像是跑表与闹钟。当执行到达边界事件所依附的活动时,启动定时器。当定时器触发时(例如在特定事件间隔后),活动会被中断,沿着边界事件继续执行

  • 图标:

定时器边界事件,用内部有一个定时器图标的标准边界事件(圆圈)表示。

  • java代码:

 

  •  xml表示:

定时器边界事件与一般边界事件一样定义。其中类型子元素为timerEventDefinition元素。

<boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport">
    <timerEventDefinition>
        <timeDuration>PT4H</timeDuration>
    </timerEventDefinition>
</boundaryEvent>
  • 注意事项:

 

 

 

2. 错误边界事件 Error Boundary Event

  • 描述:

在活动边界上的错误捕获中间(事件),或简称错误边界事件,捕获其依附的活动范围内抛出的错误。

在嵌入式子流程或者调用活动上定义错误边界事件最有意义,因为子流程会为其中的所有活动创建范围。错误由错误结束事件抛出。这样的错误会逐层向其上级父范围传播,直到找到一个错误边界事件的范围,该范围定义了匹配的错误事件定义。
当错误事件被捕获时,边界事件定义所在的活动会被销毁,同时销毁其中所有的当前执行(例如,并行活动,嵌套子流程,等等)。流程执行沿着边界事件的出口顺序流继续。
 

  • 图标:

错误边界事件,用内部有一个错误图标的标准中间事件(两层圆圈)表示。错误图标是白色的,代表捕获的含义。

  • java代码:

 

  •  xml表示:

错误边界事件与标准边界事件一样定义:

<boundaryEvent id="catchError" attachedToRef="mySubProcess">
    <errorEventDefinition errorRef="myError"/>
</boundaryEvent>

 在边界事件中,errorRef引用一个流程元素外定义的错误:

<error id="myError" errorCode="123" />
...
<process id="myProcess">
...

 errorCode用于匹配捕获的错误:

 (1)如果省略了errorRef,错误边界事件会捕获所有错误事件,无论error的errorCode是什么。
(2)如果提供了errorRef,并且其引用了存在的error,则边界事件只会捕获相同错误代码的错误。
(3)如果提供了errorRef,但BPMN 2.0文件中没有定义error,则errorRef会用作errorCode(与错误结束事件类似)。

 

  • 示例:

下面的示例流程展示了如何使用错误结束事件。当'Review profitability (审核盈利能力)'用户任务完成,并指出提供的信息不足时,会抛出错误。当这个错误被子流程边界捕获时,'Review sales lead (审核销售线索)'子流程中的所有运行中活动都会被销毁(即使'Reviewcustomer rating 审核客户等级'还没有完成),并创建'Provide additional details (提供更多信息)'用户任务

 


3. 信号边界事件 Signal Boundary Event

  • 描述:

依附在活动边界上的信号捕获中间(事件),或简称信号边界事件,捕获与其信号定义具有相同信号名的信号。

请注意:与其他事件例如错误边界事件不同的是,信号边界事件不只是捕获其所依附范围抛出的信号。信号边界事件为全局范围(广播)的,意味着信号可以从任何地方抛出,甚至是不同的流程实例。
请注意:与其他事件如错误事件不同,信号在被捕获后不会被消耗。如果有两个激活的信号边界事件,捕获相同的信号事件,则两个边界事件都会被触发,哪怕它们不在同一个流程实例里。
 

  • 图标:

信号边界事件,用内部有一个信号图标的标准中间事件(两层圆圈)表示。信号图标是白色的,代表捕获的含义。

  • java代码:

 

  •  xml表示:

信号边界事件与标准边界事件一样定义:

<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true">
    <signalEventDefinition signalRef="alertSignal"/>
</boundaryEvent>

 

 

 


4. 消息边界事件 Message Boundary Event

  • 描述:

在活动边界上的消息捕获中间(事件),或简称消息边界事件,捕获与其消息定义具有相同消息名的消息。
 

  • 图标:

消息边界事件,用内部有一个消息图标的标准中间事件(两层圆圈)表示。信号图标是白色的,代表捕获的含义。

请注意消息边界事件既可以是中断型的(右手边),也可以是非中断型的(左手边)。
 

  • java代码:

 

  •  xml表示:

消息边界事件与标准边界事件一样定义:

<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true">
    <messageEventDefinition messageRef="newCustomerMessage"/>
</boundaryEvent>

 

 

 


5. 取消边界事件 Cancel Boundary Even

  • 描述:

依附在事务子流程边界上的取消捕获中间(事件),或简称取消边界事件,在事务取消时触发。当取消边界事件触发时,首先会中断当前范围的所有活动执行。接下来,启动事务范围内所有有效的的补偿边界事件(compensation boundary event)。补偿会同步执行,也就是说在离开事务前,边界事件会等待补偿完成。当补偿完成时,使用取消边界事件的出口顺序流,离开事务子流程。
 

  • 图标:

取消边界事件,用内部有一个取消图标的标准中间事件(两层圆圈)表示。取消图标是白色的(未填充),代表捕获的含义。


 

  • java代码:

 

  •  xml表示:

取消边界事件与标准边界事件一样定义:

<boundaryEvent id="boundary" attachedToRef="transaction" >
    <cancelEventDefinition />
</boundaryEvent>

因为取消边界事件总是中断型的,因此不需要 cancelActivity 属性。
 

  • 注意:

(1)一个事务子流程只允许一个取消边界事件。
(2)如果事务子流程中有嵌套的子流程,只有成功完成的子流程才会触发补偿。
(3)如果取消边界事件放置在具有多实例特性的事务子流程上,如果一个实例触发了取消,则边界事件将取消所有实例。

 

 


6. 补偿边界事件 Compensation Boundary Event

  • 描述:

依附在事务子流程边界上的取消捕获中间(事件),或简称取消边界事件,在事务取消时触发。当取消边界事件触发时,首先会中断当前范围的所有活动执行。接下来,启动事务范围内所有有效的的补偿边界事件(compensation boundary event)。补偿会同依附在活动边界上的补偿捕获中间(事件),或简称补偿边界事件,可以为活动附加补偿处理器。
补偿边界事件必须通过直接关联的方式,引用单个的补偿处理器。
补偿边界事件与其它边界事件的活动策略不同。其它边界事件,例如信号边界事件,当其依附的活动启动时激活;当离开该活动时,会被解除,并取消相应的事件订阅。而补偿边界事件不是这样。补偿边界事件在其依附的活动成功完成时激活,同时创建补偿事件的相应订阅。当补偿事件被触发,或者相应的流程实例结束时,才会移除订阅。请考虑下列因素:
(1)当补偿被触发时,补偿边界事件关联的补偿处理器会被调用,次数与其依附的活动成功完成的次数相同。
(2)如果补偿边界事件依附在具有多实例特性的活动上,则会为每一个实例创建补偿事件订阅。
(3)如果补偿边界事件依附在位于循环内部的活动上,则每次该活动执行时,都会创建一个补偿事件订阅。
(4)如果流程实例结束,则取消补偿事件的订阅。
 

  • 图标:

补偿边界事件,用内部有一个补偿图标的标准中间事件(两层圆圈)表示。补偿图标是白色的(未填充),代表捕获的含义。另外,补偿边界事件使用单向连接关联补偿处理器,如下图所示:


 

  • java代码:

 

  •  xml表示:

补偿边界事件与标准边界事件一样定义:

<boundaryEvent id="compensateBookHotelEvt" attachedToRef="bookHotel" >
    <compensateEventDefinition />
</boundaryEvent>
<association associationDirection="One" id="a1" sourceRef="compensateBookHotelEvt" targetRef="undoBookHotel" />
<serviceTask id="undoBookHotel" isForCompensation="true" activiti:class="..." />

补偿边界事件在活动完成后才激活,因此不支持 cancelActivity 属性。
 

  • 注意:

(1)嵌入式子流程不支持补偿边界事件。

 


五、 捕获中间事件 Intermediate Catching Events

所有的捕获中间事件都使用相同方式定义:
 

<intermediateCatchEvent id="myIntermediateCatchEvent" >
    <XXXEventDefinition/>
</intermediateCatchEvent>

捕获中间事件由下列(元素)定义
(1)唯一标识符(流程范围)
(2)定义了捕获中间事件类型的,XXXEventDefinition形式的XML子元素(例如TimerEventDefinition等)。查阅特定中间捕获事件类型,以了解更多细节


1. 定时器捕获中间事件 Timer Intermediate Catching Event

  • 描述:

定时器捕获中间事件的行为像是跑表。当执行到达捕获事件活动(catching event activity)时,启动定时器;当定时器触发时(例如在一段时间间隔后),沿定时器中间事件的出口顺序流继续执行。
 

  • 图标:

定时器中间事件,用内部有定时器图标的中间捕获事件表示

 

  • java代码:

 

  •  xml表示:

定时器中间事件与捕获中间事件一样定义。指定类型的子元素为timerEventDefinition元素:

<intermediateCatchEvent id="timer">
    <timerEventDefinition>
        <timeDuration>PT5M</timeDuration>
    </timerEventDefinition>
</intermediateCatchEvent>

查看定时器事件定义了解详细配置。

  • 注意:

 

 

 

 


2. 信号捕获中间事件 Signal Intermediate Catching Event

  • 描述:

信号捕获中间事件,捕获与其引用的信号定义具有相同信号名称的信号。
请注意:与其他事件如错误事件不同,信号在被捕获后不会被消耗。如果有两个激活的信号中间事件,捕获相同的信号事件,则两个中间事件都会被触发,哪怕它们不在同一个流程实例里
 

  • 图标:

信号捕获中间事件,用内部有信号图标的标准中间事件(两层圆圈)表示。信号图标是白色的(未填充),代表捕获的含义。

 

  • java代码:

 

  •  xml表示:

信号中间事件与捕获中间事件一样定义。指定类型的子元素为signalEventDefinition元素。

<intermediateCatchEvent id="signal">
    <signalEventDefinition signalRef="newCustomerSignal" />
</intermediateCatchEvent>

 

  • 注意:

 

 

 


3. 消息捕获中间事件 Message Intermediate Catching Event

  • 描述:

消息捕获中间事件,捕获特定名字的消息。
 

  • 图标:

消息捕获中间事件,用内部有消息图标的标准中间事件(两层圆圈)表示。消息图标是白色的(未填充),代表捕获的含义。

 

  • java代码:

 

  •  xml表示:

消息中间事件与捕获中间事件一样定义。指定类型的子元素为messageEventDefinition元素。

<intermediateCatchEvent id="message">
    <messageEventDefinition signalRef="newCustomerMessage" />
</intermediateCatchEvent>

 

  • 注意:

 

 

 


六、抛出中间事件 Intermediate Throwing Event

所有的抛出中间事件都使用相同方式定义:

<intermediateThrowEvent id="myIntermediateThrowEvent" >
    <XXXEventDefinition/>
</intermediateThrowEvent>

抛出中间事件由下列(元素)定义
(1)唯一标识符(流程范围)
(2)定义了抛出中间事件类型的,XXXEventDefinition形式的XML子元素(例如signalEventDefinition等)。查阅特定中间抛出事件类型,以了解更多细节
 


1. 空抛出中间事件 Intermediate Throwing None Event

  • 描述:

下面的流程图展示了空中间事件的简单例子,其用于指示流程已经到达了某种状态

基本上添加一个执行监听器 execution listener后,空中间事件就可以成为很好的监视某些KPI(Key Performance Indicators 关键绩效指标)的钩子。
 

  • 图标:

 

 

  • java代码:

 

  •  xml表示:

 

<intermediateThrowEvent id="noneEvent">
    <extensionElements>
        <activiti:executionListener 
 class="org.activiti.engine.test.bpmn.event.IntermediateNoneEventTest$MyExecutionListener" 
 event="start" />
    </extensionElements>
</intermediateThrowEvent>

你也可以添加一些自己的代码,将部分事件发送给你的BAM(Business Activity Monitoring 业务活动监控)工具,或者DWH(DataWarehouse 数据仓库)。引擎本身不会在事件中做任何事情,只是从中穿过。
 

  • 注意:

 

 

 

 

 

 

 


2. 信号抛出中间事件 Signal Intermediate Throwing Event

  • 描述:

信号抛出中间事件,抛出已定义信号的信号事件。

在Activiti中,信号会广播至所有的激活的处理器(也就是说,所有的捕获信号事件)。信号可以同步或异步地发布。
(1)在默认配置中,信号同步地传递。这意味着抛出(信号的)流程实例会等待,直到信号传递至所有的捕获(信号的)流程实例。所有的捕获流程实例也会在与抛出流程实例相同的事务中,也就是说如果收到通知的流程实例中,有一个实例产生了技术错误(抛出异常),则所有相关的实例都会失败。
(2)信号也可以异步地传递。这是由到达抛出信号事件时,激活的是哪一个(发送)处理器来决定的。对于每个激活的处理器,JobExecutor会为其存储并传递一个异步通知消息,asynchronous notification message(作业 Job)。
 

  • 图标:

消息抛出中间事件,用内部有信号图标的标准中间事件(两层圆圈)表示。信号图标是黑色的(已填充),代表抛出的含义。

 

  • java代码:

 

  •  xml表示:

信号中间事件与抛出中间事件一样定义。指定类型的子元素为signalEventDefinition元素。

<intermediateThrowEvent id="signal">
    <signalEventDefinition signalRef="newCustomerSignal" />
</intermediateThrowEvent>

异步信号事件像这样定义:
 

<intermediateThrowEvent id="signal">
    <signalEventDefinition signalRef="newCustomerSignal" activiti:async="true" />
</intermediateThrowEvent>
  • 注意:

 

 

 

 


3. 补偿抛出中间事件 Compensation Intermediate Throwing Event

  • 描述:

补偿抛出中间事件,可用于触发补偿。
触发补偿:补偿既可以为设计的活动触发,也可以为补偿事件所在的范围触发。补偿由活动所关联的补偿处理器执行。

(1)抛出补偿时,活动关联的补偿处理器执行的次数,与活动成功完成的次数相同。
(2)如果为当前范围抛出了补偿,则当前范围中所有的活动都会被补偿,包括并行分支上的活动。
(3)补偿分层触发:如果将要被补偿的活动是一个子流程,则该子流程中所有的活动都会触发补偿。如果该子流程有嵌套的活动,则会递归地抛出补偿。然而,补偿不会传播至流程的上层:如果子流程中触发了补偿,该补偿不会传播至子流程范围外的活动。BPMN规范指出,补偿为“与子流程在相同级别”的活动触发。
(4)在Activiti中,补偿按照执行的相反顺序运行。这意味着最后完成的活动会第一个补偿,等等。
(5)补偿抛出中间事件,可用于补偿已经成功完成的事务子流程。

  请注意:如果抛出补偿的范围中有一个子流程,而该子流程包含有关联了补偿处理器的活动,则当抛出补偿时,只有当该子流程成功完成的情况,补偿才会传播至该子流程。如果子流程内嵌套的部分活动已经完成,并附加了补偿处理器,则如果包含这些活动的子流程还没有完成,这 些补偿处理器不会执行。参考下面的例子:

 

 在这个流程中,有两个并行的执行。一个执行嵌入子流程,另一个执行“charge credit card(信用卡付款)”活动。假定两个执行都已开始,且第一个并行执行正等待用户完成“review bookings(检查预定)”任务。第二个执行进行了“charge credit card(信用卡付款)”活动的操作,抛出了一个错误,导致“cancel reservations(取消预订)”事件触发补偿。这时并行子流程还未完成,意味着补偿不会传播至该子流程,因此不会执行“cancel hotel reservation(取消酒店预订)”补偿处理器。而如果“cancel reservations(取消预订)”运行前,这个用户任务(因此该嵌入式子流程也)已经完成,则补偿会传播至该嵌入式子流程。

 流程变量:当补偿嵌入式子流程时,用于执行补偿处理器的执行,可以以变量在子流程完成时所处的状态,访问子流程的局部流程变量。为了实现这一点,会为范围执行(为执行子流程所创建的执行)所关联的流程变量,进行快照。意味着:

 (1)子流程范围内创建的并行执行所添加的变量,补偿执行器无法访问。
 (2)上层的执行关联的流程变量(例如流程实例的执行关联的流程变量),不在该快照中:补偿处理器(本就)可以以其在抛出补偿时所处的状态,访问这些流程变量。
 (3)只会为嵌入式子流程,而不会为其他活动,进行变量快照。

目前的限制:
(1)目前不支持 waitForCompletion="false" 。当补偿抛出中间事件触发补偿时,只有在补偿成功完成时,才会离开该事件。
(2)补偿现在由并行执行来运行。该并行执行按照补偿活动完成的逆序启动。Activiti的后续版本可能会添加选项,使补偿可以按(活动完成的)顺序运行。
(3)补偿不会传播至调用活动(call activity)生成的子流程。

 

  • 图标:

补偿抛出中间事件,用内部有补偿图标的标准中间事件(两层圆圈)表示。补偿图标是黑色的(已填充),代表抛出的含义。

 

  • java代码:

 

  •  xml表示:

补偿中间事件与抛出中间事件一样定义。指定类型的子元素为compensateEventDefinition元素。

<intermediateThrowEvent id="throwCompensation">
    <compensateEventDefinition />
</intermediateThrowEvent>

另外, activityRef 可选项可用于为指定的范围/活动触发补偿:

<intermediateThrowEvent id="throwCompensation">
    <compensateEventDefinition activityRef="bookHotel" />
</intermediateThrowEvent>
  • 注意:

 

 

 

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青苔猿猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值