Activiti工作流框架中邊界事件和捕獲事件以及觸發(fā)事件詳解

邊界事件

  • 邊界事件都是捕獲事件,它會附在一個環(huán)節(jié)上
  • 邊界事件是捕獲事件,不可能觸發(fā)事件:
    • 當節(jié)點運行時,事件會監(jiān)聽對應的觸發(fā)類型
    • 當事件被捕獲,節(jié)點就會中斷,同時執(zhí)行事件的后續(xù)連線
  • 邊界事件的定義方式都一樣:
<boundaryEvent id="myBoundaryEvent" attachedToRef="theActivity">
      <XXXEventDefinition/>
</boundaryEvent>
  • 邊界事件使用如下方式進行定義:
    • 唯一標識:流程范圍
    • 使用caught屬性引用事件的節(jié)點,注意邊界事件和它們附加的節(jié)點在同一級別上:比如,邊界事件不是包含在節(jié)點內(nèi)的
    • 格式為XXXEventDefinition的XML子元素 (比如,TimerEventDefinition,ErrorEventDefinition...)定義了邊界事件的類型

定時邊界事件

描述
  • 定時邊界事件就是一個暫停等待警告的時鐘
  • 當流程執(zhí)行到綁定了邊界事件的環(huán)節(jié),會啟動一個定時器
  • 當定時器觸發(fā)時(一定時間之內(nèi)),環(huán)節(jié)就會中斷,并沿著定時邊界事件的外出連線繼續(xù)執(zhí)行
圖形標記
  • 定時邊界事件是一個標準的邊界事件(邊界上的一個圓圈),內(nèi)部是一個定時器小圖標
    在這里插入圖片描述
XML內(nèi)容
  • 定時器邊界任務定義是一個標準的邊界事件,指定類型的子元素是timerEventDefinition元素
<boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport">
   <timerEventDefinition>
    <timeDuration>PT4H</timeDuration>
  </timerEventDefinition>
</boundaryEvent>
  • 在流程圖中,圓圈邊線是虛線:


    在這里插入圖片描述
  • 經(jīng)典應用場景: 發(fā)送通知郵件,但是不打斷正常流程的執(zhí)行
    • 中斷和非中斷的事件還是有區(qū)別的
      • 默認是中斷事件
      • 非中斷事件的情況,不會中斷原始環(huán)節(jié),那個環(huán)節(jié)還停留在原地
      • 對應的,會創(chuàng)建一個新分支,并沿著事件的流向繼續(xù)執(zhí)行.在XML內(nèi)容中,要把cancelActivity屬性設置為false
      <boundaryEvent id="escalationTimer" cancelActivity="false" attachedToRef="firstLineSupport"/>
      
  • ==注意:== 邊界定時事件只能在job執(zhí)行器啟用時使用
    • 比如:把activiti.cfg.xml中的jobExecutorActivate設置為true,默認job執(zhí)行器是禁用的
邊界事件的問題
  • 同步問題: 邊界事件后面不能有多條外出連線
  • 解決這個問題的方法是在一個連線后使用并發(fā)網(wǎng)關
    -

錯誤邊界事件

描述
  • 錯誤邊界事件: 節(jié)點邊界上的中間捕獲錯誤事件,會捕獲節(jié)點范圍內(nèi)拋出的錯誤
  • 定義一個邊界錯誤事件,大多用于內(nèi)嵌子流程或者調(diào)用節(jié)點
    • 對于子流程的情況,它會為所有內(nèi)部的節(jié)點創(chuàng)建一個作用范圍
    • 錯誤是由錯誤結束事件拋出的.這個錯誤會傳遞給上層作用域,直到找到一個錯誤事件定義相匹配的邊界錯誤事件
  • 當捕獲了錯誤事件時 ,邊界任務綁定的節(jié)點就會銷毀,也會銷毀內(nèi)部所有的執(zhí)行分支(同步節(jié)點,內(nèi)嵌子流程...).流程執(zhí)行會繼續(xù)沿著邊界事件的外出連線繼續(xù)執(zhí)行
圖形標記
  • 錯誤邊界事件顯示成一個普通的中間事件(圓圈內(nèi)部有一個小圓圈)放在節(jié)點的標記上,內(nèi)部有一個錯誤小圖標.錯誤小圖標是白色的,表示它是一個捕獲事件
    在這里插入圖片描述
XML內(nèi)容
  • 邊界錯誤事件定義為普通的邊界事件:
<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使用
錯誤邊界事件實例
  • 如何使用錯誤結束事件的流程實例
    • 當完成審核盈利這個用戶任務時,如果沒有提供足夠的信息,就會拋出錯誤
    • 錯誤會被子流程的邊界任務捕獲,所有回顧銷售子流程中的所有節(jié)點都會銷毀,即使審核客戶比率還沒有完成,并創(chuàng)建一個提供更多信息的用戶任務


      在這里插入圖片描述

信號邊界事件

描述
  • 節(jié)點邊界的中間捕獲信號,會捕獲信號定義引用的相同信號名的信號
  • 與其他事件(比如邊界錯誤事件)不同,邊界信號事件不只捕獲綁定方位的信號.信號事件是一個全局的范圍(廣播語義),就是說信號可以在任何地方觸發(fā),即便是不同的流程實例
  • 和其他事件(比如邊界錯誤事件)不同 ,捕獲信號后,不會停止信號的傳播. 如果有兩個信號邊界事件,捕獲相同的信號事件,兩個邊界事件都會被觸發(fā),即使在不同的流程實例中
圖形標記
  • 邊界信號事件顯示為普通的中間事件(圓圈里有個小圓圈),位置在節(jié)點的邊緣, 內(nèi)部有一個信號小圖標.信號圖標是白色的(未填充),表示捕獲的意思
    在這里插入圖片描述
XML內(nèi)容
  • 邊界信號事件定義為普通的邊界事件:
<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true">
          <signalEventDefinition signalRef="alertSignal"/>
</boundaryEvent>

消息邊界事件

描述
  • 節(jié)點邊界上的中間捕獲消息, 根據(jù)引用的消息定義捕獲相同消息名稱的消息
圖形標記
  • 邊界消息事件顯示成一個普通的中間事件(圓圈里有個小圓圈),位于節(jié)點邊緣,內(nèi)部是一個消息小圖標.消息圖標是白色(無填充),表示捕獲的意思
    在這里插入圖片描述
  • ==注意:== 邊界消息事件可能是非中斷(左側) 或者中斷(右側)
XML內(nèi)容
  • 邊界消息事件定義為標準的邊界事件
<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true">
          <messageEventDefinition messageRef="newCustomerMessage"/>
</boundaryEvent>

取消邊界事件

描述
  • 在事務性子流程的邊界上的中間捕獲取消
  • 事務取消時觸發(fā),當取消邊界事件觸發(fā)時:
    • 首先中斷當前作用域的所有執(zhí)行
    • 然后開始補償事務內(nèi)的所有激活的補償邊界事件.補償是同步執(zhí)行的:離開事務前,邊界事務會等待補償執(zhí)行完畢
    • 當補償完成后,事務子流程會沿著取消邊界事務的外出連線繼續(xù)執(zhí)行
  • ==注意:==
    • 每個事務子流程只能有一個取消邊界事件
    • 如果事務子流程包含內(nèi)嵌子流程,補償只會觸發(fā)已經(jīng)成功完成的子流程
    • 如果取消邊界子流程對應的事務子流程配置為多實例,如果一個實例觸發(fā)了取消,就會取消所有實例
圖形標記
  • 取消邊界事件顯示為了一個普通的中間事件(圓圈里套小圓圈),在節(jié)點的邊緣,內(nèi)部是一個取消小圖標.取消圖標是白色(無填充),表明是捕獲的意思


    在這里插入圖片描述
XML內(nèi)容
  • 取消邊界事件定義為普通邊界事件
<boundaryEvent id="boundary" attachedToRef="transaction" >
          <cancelEventDefinition />
</boundaryEvent>
  • 取消邊界事件都是中斷的,不需要使用cancelActivity屬性

補償邊界事件

描述
  • 節(jié)點邊界的中間捕獲補償
  • 用來設置一個節(jié)點的補償處理器
  • 補償邊界事件必須使用直接引用設置唯一的補償處理器
  • 補償邊界事件與其他邊界事件的策略不同:
    • 其他邊界事件(信號邊界事件)當?shù)竭_關聯(lián)的節(jié)點就會被激活.離開節(jié)點時,就會掛起,對應的事件訂閱也會取消
    • 補償邊界事件在關聯(lián)的節(jié)點成功完成時激活,當補償事件觸發(fā)或對應流程實例結束時,事件訂閱才會刪除
  • 補償邊界事件遵循如下規(guī)則:
    • 補償觸發(fā)時,補償邊界事件對應的補償處理器會調(diào)用相同次數(shù),根據(jù)它對應的節(jié)點的成功次數(shù)
    • 如果補償邊界事件關聯(lián)到多實例節(jié)點,補償事件會訂閱每個實例
    • 如果補償邊界事件關聯(lián)的節(jié)點中包含循環(huán),補償事件會在每次節(jié)點執(zhí)行時進行訂閱
    • 如果流程實例結束,訂閱的補償事件都會結束
  • 補償邊界事件不支持內(nèi)嵌子流程
圖形標記
  • 補償邊界事件顯示為標準中間事件(圓圈里套圓圈),位于節(jié)點邊緣,內(nèi)部有一個補償小圖標.補償圖標是白色的(無填充),表示捕獲的意思
  • 下圖演示使用無方向的關聯(lián),為邊界事件設置補償處理器:


    在這里插入圖片描述
XML內(nèi)容
  • 補償邊界事件定義為標準邊界事件
<boundaryEvent id="compensateBookHotelEvt" attachedToRef="bookHotel" >
          <compensateEventDefinition />
</boundaryEvent>

<association associationDirection="One" id="a1"  sourceRef="compensateBookHotelEvt" targetRef="undoBookHotel" />

<serviceTask id="undoBookHotel" isForCompensation="true" activiti:class="..." />
  • 補償邊界事件在節(jié)點成功完成后激活, 不支持cancelActivity屬性

中間捕獲事件

  • 所有中間捕獲事件都使用同樣的方式定義:
<intermediateCatchEvent id="myIntermediateCatchEvent" >
      <XXXEventDefinition/>
</intermediateCatchEvent>
  • 中間捕獲事件的定義:
    • 唯一標識(流程范圍內(nèi))
    • 一個結構為XXXEventDefinition的XML子元素(TimerEventDefinition)定義了中間捕獲事件的類型

定時中間捕獲事件

描述
  • 定時中間事件作為一個監(jiān)聽器
  • 當執(zhí)行到達捕獲事件節(jié)點,就會啟動一個定時器.當定時器觸發(fā)(比如,一段時間之后),流程就會沿著定時中間事件的外出節(jié)點繼續(xù)執(zhí)行
圖形標記
  • 定時器中間事件顯示成標準中間捕獲事件, 內(nèi)部是一個定時器小圖標:
    在這里插入圖片描述
XML內(nèi)容
  • 定時器中間事件定義為標準中間捕獲事件. 指定類型的子元素為timerEventDefinition元素
        <intermediateCatchEvent id="timer">
            <timerEventDefinition>
                <timeDuration>PT5M</timeDuration>
            </timerEventDefinition>
        </intermediateCatchEvent>

信號中間捕獲事件

  • 中間捕獲信號事件,通過引用信號定義來捕獲相同信號名稱的信號
  • 信號中間捕獲事件與其它事件(比如錯誤事件)不同:
    • 信號不會在捕獲之后被消費
    • 如果有兩個激活的信號邊界事件捕獲相同的信號事件,兩個邊界事件都會被觸發(fā),即便在不同的流程實例中

圖形標記

  • 中間信號捕獲事件顯示為一個普通的中間事件(圓圈套圓圈),內(nèi)部有一個信號小圖標.信號小圖標是白色的(無填充),表示捕獲的意思
    在這里插入圖片描述
XML內(nèi)容
  • 信號中間事件定義為普通的中間捕獲事件. 對應類型的子元素是signalEventDefinition元素
<intermediateCatchEvent id="signal">
        <signalEventDefinition signalRef="newCustomerSignal" />
</intermediateCatchEvent>

消息中間捕獲事件

描述
  • 中間捕獲消息事件,捕獲特定名稱的消息
圖形標記
  • 中間捕獲消息事件顯示為普通中間事件(圓圈套圓圈),內(nèi)部是一個消息小圖標.消息圖標是白色的(無填充),表示捕獲的意思
    在這里插入圖片描述
XML內(nèi)容
  • 消息中間事件定義為標準中間捕獲事件. 指定類型的子元素是messageEventDefinition元素
<intermediateCatchEvent id="message">
        <messageEventDefinition signalRef="newCustomerMessage" />
</intermediateCatchEvent>

內(nèi)部觸發(fā)事件

  • 所有內(nèi)部觸發(fā)事件的定義都是一樣的:
<intermediateThrowEvent id="myIntermediateThrowEvent" >
      <XXXEventDefinition/>
</intermediateThrowEvent>
  • 內(nèi)部觸發(fā)事件定義包含:
    • 唯一標識(流程范圍)
    • 使用格式為XXXEventDefinition的XML子元素(比如signalEventDefinition等)定義中間觸發(fā)事件的類型
中間觸發(fā)空事件
  • 空中間觸發(fā)事件流程圖,用于表示流程中的某個狀態(tài)


    在這里插入圖片描述
  • 可以添加執(zhí)行監(jiān)聽器:
<intermediateThrowEvent id="noneEvent">
  <extensionElements>
    <activiti:executionListener class="org.activiti.engine.test.bpmn.event.IntermediateNoneEventTest$MyExecutionListener" event="start" />
  </extensionElements>
</intermediateThrowEvent>
  • 可以添加自己的代碼,把事件發(fā)送給BAM工具或DWH.引擎不會為這個事件做任何事情,它直接徑直通過

信號中間觸發(fā)事件

描述
  • 信號中間觸發(fā)事件為定義的信號拋出一個信號事件
  • 在activiti中,信號會廣播到所有激活的處理器中.信號可以通過同步和異步方式發(fā)布
    • 默認配置下,信號是同步發(fā)送的:
      • 拋出事件的流程實例會等到信號發(fā)送給所有捕獲流程實例才繼續(xù)執(zhí)行
      • 捕獲流程實例也會在觸發(fā)流程實例的同一個事務中執(zhí)行
      • 如果某個監(jiān)聽流程出現(xiàn)了技術問題(拋出異常),所有相關的實例都會失敗
    • 信號也可以異步發(fā)送:
      • 會在到達拋出信號事件后決定哪些處理器是激活的
      • 對這些激活的處理器,會保存一個異步提醒消息(任務),并發(fā)送給jobExecutor
圖形標記
  • 中間信號觸發(fā)事件顯示為普通中間事件(圓圈套圓圈),內(nèi)部又一個信號小圖標,信號圖標是黑色的(有填充),表示觸發(fā)的意思
    在這里插入圖片描述
XML內(nèi)容
  • 消息中間事件定義為標準中間觸發(fā)事件. 指定類型的子元素是signalEventDefinition元素
<intermediateThrowEvent id="signal">
        <signalEventDefinition signalRef="newCustomerSignal" />
</intermediateThrowEvent>
  • 異步信號事件如下:
<intermediateThrowEvent id="signal">
        <signalEventDefinition signalRef="newCustomerSignal" activiti:async="true" />
</intermediateThrowEvent>

補償中間觸發(fā)事件

描述
  • 用來觸發(fā)補償
  • 觸發(fā)補償:
    • 補償可以由特定節(jié)點或包含補償事件的作用域觸發(fā)
    • 補償是通過分配給節(jié)點的補償處理器來完成的
      • 當補償由節(jié)點觸發(fā),對應的補償處理器會根據(jù)節(jié)點成功完成的次數(shù)執(zhí)行相同次數(shù)
      • 如果補償由當前作用域觸發(fā),當前作用域的所有節(jié)點都會執(zhí)行補償,也包含并發(fā)分支
      • 補償?shù)挠|發(fā)是繼承式的:
        • 如果執(zhí)行補償?shù)墓?jié)點是子流程,補償會作用到子流程中包含的所有節(jié)點
        • 如果子流程是內(nèi)嵌節(jié)點,補償會遞歸觸發(fā)
        • 補償不會傳播到流程的上層
        • 如果補償在子流程中觸發(fā),不會傳播到子流程范圍外
        • bpmn規(guī)范定義,由節(jié)點觸發(fā)的流程只會作用到子流程同一級別
      • activiti的補償執(zhí)行次序與流程執(zhí)行順序相反: 最后完成的節(jié)點會最先執(zhí)行補償
      • 補償中間觸發(fā)事件可以用來補償成功完成的事務性子流程
  • ==注意:==
    • 如果補償被一個包含子流程的作用域觸發(fā),子流程還包含了關聯(lián)補償處理器的節(jié)點, 如果它已經(jīng)成功完成了,補償只會傳播到子流程
    • 如果子流程中的節(jié)點也完成了,并關聯(lián)了補償處理器,如果子流程包含的這些節(jié)點還沒有完成,就不會執(zhí)行補償處理器


      在這里插入圖片描述

      這個流程中,我們有兩個并發(fā)分支,一個分支是內(nèi)嵌子流程,一個是使用信用卡節(jié)點.假設兩個分支都啟動了,第一個分支等待用戶完成審核預定任務.第二個分支執(zhí)行使用信用卡節(jié)點, 并發(fā)生了一個錯誤,這導致取消預定事件,并觸發(fā)補償.這時,并發(fā)子流程還沒有結束,意味著補償事件不會傳播給子流程, 所以取消旅店預定這個補償處理器不會執(zhí)行.如果用戶任務(就是內(nèi)嵌子流程)在取消預定之前完成了,補償就會傳播給內(nèi)嵌子流程

  • 流程變量:
    • 當補償內(nèi)嵌子流程時,用來執(zhí)行補償處理器的分支可以訪問子流程的本地流程實例,因為這時是子流程完成的分支
    • 為了實現(xiàn)這個功能,流程變量的快照會分配給分支(為執(zhí)行子流程而創(chuàng)建的分支)有以下限制條件:
      • 補償處理器無法訪問子流程內(nèi)部創(chuàng)建的,添加到同步分支的變量
      • 分配給分支的流程變量在繼承關系上層的(分配給流程實例的流程變量沒有包含在快照中):補償觸發(fā)時,補償處理器通過它們所在的地方訪問這些流程變量
      • 變量快照只用于內(nèi)嵌子流程,不適用其他節(jié)點
 已知限制:
 1. waitForCompletion="false"還不支持。當補償使用中間觸發(fā)補償事件觸發(fā)時, 事件沒有等待,在補償成功結束后
 2. 補償自己由并發(fā)分支執(zhí)行。并發(fā)分支的執(zhí)行順序與被補償?shù)墓?jié)點完成次序相反。 未來activiti可能支持選項來順序執(zhí)行補償
 3. 補償不會傳播給callActivity調(diào)用的子流程實例
圖形標記
  • 中間補償觸發(fā)事件顯示為標準中間事件(圓圈套圓圈),內(nèi)部是一個補償小圖標.補償圖標是黑色的(有填充),表示觸發(fā)的意思
    在這里插入圖片描述
XML內(nèi)容
  • 補償中間事件定義為普通的中間觸發(fā)事件. 對應類型的子元素是compensateEventDefinition元素
<intermediateThrowEvent id="throwCompensation">
        <compensateEventDefinition />
</intermediateThrowEvent>
  • 可選參數(shù)activityRef可以用來觸發(fā)特定作用域/節(jié)點的補償
<intermediateThrowEvent id="throwCompensation">
        <compensateEventDefinition activityRef="bookHotel" />
</intermediateThrowEvent>
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容