camunda之——取消和补偿事件(Cancel and Compensation Events)

取消事件(Cancel Events):

一、取消结束事件(Cancel End Event):

       取消结束事件只能与事务子流程配合使用。当流程到达取消结束事件,一个取消事件将会被抛出,这个取消事件必须被一个取消边界事件捕获。这取消边界事件随后会取消这个事务并触发补偿。

二、取消边界事件(Cancel Boundary Event):

       依附于事务子流程的上的中间捕获取消边界事件,或者简称取消边界事件。当一个事务被取消时,取消边界事件将会被触发。当取消边界事件被触发后,它首先打断在这个作用域下的所有活动的执行。接下来,它会开始执行补偿所有在这个事务的作用域内的活动的补偿边界事件。补偿行为是同步的,就是说边界事件会一直等待到补偿事件完成后才会离开事务。即当补偿完成后,这个事务子流程会离开取消边界事件。

注意:
       1.一个事务子流程只允许有一个取消边界事件
       2.如果事务子流程有嵌套的子流程,只有那些子流程已经完全成功的子流程才会触发补偿
       3.如果取消边界事件放置在多个流程实例的事务子流程上,如果一个实例触发取消,所有的实例都会取消。

       一个典型的边界事件的定义:


  

       因为取消边界事件总是可中断的,所以不需要cancelActivity属性

补偿事件(Compensation Events):

一、中间抛出补偿事件(Intermediate Throwing Compensation Event):

       中间抛出补偿事件用于触发一个补偿:

触发补偿:补偿事件可以被指定的活动触发,或者一个拥有补偿事件的作用域触发。补偿的执行是通过一个活动的补偿handler的execution来执行补偿
       1.当为某个活动抛出一个补偿时,相关的补偿handler执行的次数与活动完成的次数相同。
       2.如果是在当前作用域抛出的补偿,则当前作用域的所有活动都将要被补偿,包括并发分支上的活动。
       3.补偿事件会被有层次的触发:如果被补偿的活动时一个子流程,所有包含在这个子流程内的活动都会被触发补偿。如果这个子流程有嵌套的活动,补偿事件会递归的向下抛出。但是补偿事件不会广播到比这个流程高的层级。如果一个补偿在一个子流程内触发,它不会广播到这个子流程的作用域外的活动上去。BPMN规范规定对“同一级别的子流程”上的活动触发补偿。
       4.补偿被补偿事件子流程(compensation event subprocess)消费,如果一个被补偿的活动是一个子流程,并且这个子流程包含一个补偿事件子流程,且这个流程被补偿开始事件触发,那么补偿触发的是这个补偿事件子流程而不是触发这个活动包含的子流程。
       5.补偿是以相反的顺序执行的,这意味着最后完成的活动,最先获得补偿。
       6.中间抛出补偿事件可以用来补偿已经完成的事物子流程

注意:如果补偿在一个作用域内被抛出,这个作用域包含一个子流程并且这个子流程包含一个带有补偿handler的活动,只有当子流程完成时,并且补偿被抛出,补偿才会传播到子流程的补偿handler。如果嵌套在子流程中的某些活动已完成并有附加补偿处理程序,则如果包含这些活动的子流程尚未完成,则补偿行为不会被执行。 考虑以下示例:

图1:补偿事件

       在图示的流程中,有两个并发的执行,一个执行被包含的子流程,一个执行信用卡充值活动。我们假设两个执行都已经开始了,并且第一个第一个执行正在等待一个用户去完成检查预定任务。第二个执行正在执行信用卡充值的活动并且一个错误被抛出,这个错误会导致取消补偿事件触发补偿。在这时这个并行的子流程还没完成,这意味着这个补偿事件没有传播到这个子流程,因此 取消酒店预定补偿handler没有执行。如果这个检查预定活动在取消预定抛出事件之前被执行,补偿事件会传播到这个被包含的子流程里。

注意:多实例活动抛出补偿时,只有当所有的流程实例都结束了相关的补偿handler才会执行。这意味着多实例活动在被补偿前必须先被结束掉。

流程变量:在补偿一个被包含的子流程时,用于执行补偿的handler可以访问子流程完成后,子流程的本地流程变量(local process variables)。为此,子流程作用域内的流程变量将被作为快照保存起来。

由此,我们可以得出一些推论:
       1.补偿handler不会去访问当前执行中的子流程中的流程变量
       2.快照里不包含与更高层执行相关的流程变量,例如与流程实例执行相关的流程变量:补偿handler可以在补偿被抛出时的状态下去访问这些流程变量
       3.变量快照只在被包含的子流程中被采用,其他活动不被支持
当前的一些限制:
       1.waitForCompletion="false"在补偿事件中是不被支持的,当用中间抛出补偿事件(intermediate throwing compensation)触发补偿时,在补偿完成后只剩下这个事件(the event is only left after compensation completed successfully)
       2.补偿本身是被并发执行的,这个并发执行的顺序与被不补偿活动完成的顺序相反,之后的版本可能会包含一个可选的补偿执行顺序。
       3.补偿不会广播到由调用活动产生子流程中去(懵逼脸)

定义一个中间补偿抛出事件:

       补偿中间事件被定义为一个中间抛出事件,在这个例子中特定类型的子元素是compensateEventDefinition元素:


  

       另外,可选参数activityRef可以触发一个特定活动或者作用域的补偿:


  

二、补偿结束事件(Compensation End Event):

       补偿结束事件触发补偿,并且结束当前执行路径。它与补偿中间抛出事件具有相同的行为和限制。


  

三、补偿边界事件(Compensation Boundary Event):

       依附于一个活动的边界上的中间捕获补偿事件。简称补偿边界事件。用作附着一个补偿handler到一个活动或者一个被包含的子流程上。
       补偿边界事件必须直接引用一个相关的补偿handler。
       与其他边界事件相比,补偿边界事件有不同的行为策略。其他的边界事件,例如信号边界事件,当活动到达时,信号边界事件就开始了,当活动结束,它也就结束了,并且相关的事件订阅也被取消。补偿边界事件不同,补偿边界事件只有当被依附的活动完全结束后,才会被激活。与此同时,相关的边界事件订阅被创建。当边界事件被触发或者相关的流程实例结束,这个订阅也会被删除。

这就引出了下面的几点:
       1.当补偿被触发时,被补偿边界事件依附的活动完成的同时,这个与补偿边界事件关联的补偿handler被调用。
       2.如果一个补偿事件依附了一个多实例活动,那么会为每一个补偿事件创建一个订阅。
       3.如果补偿边界事件依附于一个活动,且这个活动被包含在一个循环中。则每次这个活动被执行时,都会给它创建一个补偿事件订阅。
       4.如果流程实例结束,那么补偿事件订阅也就将被取消掉。

定义一个补偿边界事件:

  





       因为补偿边界事件是在活动完全结束后才被激活的,所以cancelActivity属性是不被支持的。

四、补偿开始事件(Compensation Start Event):

       补偿开始事件只被用作触发一个事件子流程,它不可以被用作发起一个流程实例。这种类型的子流程被称作补偿事件子流程。

部署一个补偿事件子流程的流程定义时,需要注意一下几点:
       1.补偿事件子流程只支持被包含的子流程,不是流程级别的。因为这个限制,补偿不会传播到由调用活动产生的子流程实例。
       2.在同一层级的子流程只允许有一个补偿事件子流程
       3.带有补偿事件子流程的子流程不支持被一个补偿边界事件依赖,因为补偿事件子流程和补偿边界事件有相同的意图,所以他们只能有一个被选用。

       补偿事件子流程可以被用作一个被子流程包含的补偿handler。类似补偿边界事件依附一个子流程,补偿事件子流程也只有在补偿事件被抛出时才会被调用。在子流程完成之前,补偿事件子流程将会被调用跟子流程完成的次数相同的次数,在下面这个例子中:
图2:补偿开始事件

       上面的流程中包含一个被包含的补偿事件子流程,这个补偿事件子流程将会被补偿开始事件触发。注意,这个补偿handler与默认的补偿handler不一样,因为它是用一个特定的独立于execution指令去触发补偿活动。它也包含一个附加流程活动,这个附加逻辑无法从子流程自身派生出来。

定义一个补偿开始事件:

       下面这个xml表示一个补偿开始事件是一个带有compensateEventDefinition子元素的普通开始事件:


  
    
  
  

你可能感兴趣的:(camunda之——取消和补偿事件(Cancel and Compensation Events))