嵌入式工作流程開發!工作流 Activiti 框架中子流程的使用指南


子流程

子流程

描述
  • 子流程(Sub-process)是一個包含其他節點,網關,事件等等的節點
  • 本身就是一個流程,同時是更大流程的一部分.子流程是完全定義在父流程里的,所以叫做內嵌子流程
  • 子流程的兩種主要場景:
    • 子流程可以使用繼承式建模: 很多建模工具的子流程可以折疊,把子流程的內部細節隱藏,顯示一個高級別的端對端的業務流程總覽
    • 子流程會創建一個新的事件作用域: 子流程運行過程中拋出的事件,可以被子流程邊緣定義的邊界事件捕獲,就可以創建一個僅限於這個子流程的事件作用范圍
  • 使用子流程的限制:
    • 子流程只能包含一個空開始事件, 不能使用其他類型的開始事件,子路程必須至少有一個結束節點
    • 順序流不能跨越子流程的邊界
圖形標記
  • 子流程顯示為標准的節點(圓角矩形),下面子流程是折疊的,只顯示名稱和一個加號標記,展示了高級別的流程總覽:
    在這里插入圖片描述
  • 下面子流程是展開的,子流程的步驟都顯示在子流程邊界內:
    在這里插入圖片描述
  • 使用子流程主要是為了定義對應事件的作用域
  • 示例:
    • 調查軟件/調查引薦任務需要同步執行,兩個任務需要在同時完成,在二線支持解決之前.這里,定時器的作用域(比如節點需要及時完成)是由子流程限制的:

在這里插入圖片描述

XML內容
  • 子流程定義為subprocess元素.所有節點,網關,事件,等等.是子流程的一部分,都需要放在這個元素里
<subProcess id="subProcess">

  <startEvent id="subProcessStart" />

  ... other Sub-Process elements ...

  <endEvent id="subProcessEnd" />

 </subProcess>

事件子流程

描述
  • 事件子流程是由事件觸發的子流程.是BPMN 2.0中的新元素
  • 事件子流程可以添加到流程級別或任意子流程級別
  • 用於觸發事件子流程的事件是使用開始事件配置的,所以事件子流程是不支持空開始事件的
  • 事件子流程可以被消息事件,錯誤事件,信號事件,定時器事件,或補償事件觸發.開始事件的訂閱在包含事件子流程的作用域(流程實例或子流程)創建時就會創建.當作用域銷毀也會刪除訂閱。
  • 事件子流程可以是中斷的或非中斷的
    • 一個中斷的子流程會取消當前作用域內的所有流程
    • 非中斷事件子流程會創建一個新的同步分支
    • 中斷事件子流程只會被每個激活狀態的宿主觸發一次
    • 非中斷事件子流程可以觸發多次
    • 子流程是否是中斷的,使用事件子流程的開始事件配置
  • 事件子流程不能有任何進入和外出流程
    • 當事件觸發一個事件子流程時,輸入順序流是沒有意義的
    • 當事件子流程結束時,無論當前作用域已經結束(中斷事件子流程的情況或為非中斷,子流程生成同步分支會結束
  • 事件子流程的限制:
    • Activiti只支持中斷事件子流程
    • Activiti只支持使用錯誤開始事件或消息開始事件的事件子流程
圖像標記
  • 事件子流程可以顯示為邊框為虛線的內嵌子流程
    在這里插入圖片描述
XML內容
  • 事件子流程的XML內容與內嵌子流程一樣,但是要把triggeredByEvent屬性設置為true
<subProcess id="eventSubProcess" triggeredByEvent="true">
        ...
</subProcess>
實例
  • 使用錯誤開始事件觸發的事件子流程的實例,事件子流程是放在流程級別的,作用於流程實例
    在這里插入圖片描述
    事件子流程的XML:
<subProcess id="eventSubProcess" triggeredByEvent="true">
        <startEvent id="catchError">
                <errorEventDefinition errorRef="error" />
        </startEvent>
        <sequenceFlow id="flow2" sourceRef="catchError" targetRef="taskAfterErrorCatch" />
        <userTask id="taskAfterErrorCatch" name="Provide additional data" />
</subProcess>

事件子流程也可以添加成內嵌子流程.如果添加為內嵌子流程,其實是邊界事件的一種替代方案

  • 示例:
    • 下面兩個流程圖,兩種情況內嵌子流程會拋出一個錯誤事件,兩種情況錯誤都會被捕獲並使用一個用戶任務處理
      在這里插入圖片描述
      相對於
      在這里插入圖片描述
    • 兩種場景都會執行相同的任務,但是兩種建模的方式是不同的:
      • 內嵌子流程是使用與執行作用域宿主相同的流程執行的:
        • 意思是內嵌子流程可以訪問它作用域內的內部變量
        • 當使用邊界事件時,執行內嵌子流程的流程會刪除, 並生成一個流程根據邊界事件的順序流繼續執行,這意味着內嵌子流程創建的變量不再起作用
      • 當使用事件子流程時,事件是完全由它添加的子流程處理的.
        • 當使用邊界事件時,事件由父流程處理
  • 這兩個不同點可以幫助決定是使用邊界事件(內嵌子流程)還是內嵌事件子流程(事件子流程) 來解決特定的流程建模或者實現問題

事務子流程

描述
  • 事務子流程是內嵌子流程, 可以用來把多個流程放到一個事務里
  • 事務是一個邏輯單元, 可以把一些單獨的節點放在一起, 這樣它們就可以一起成功或一起失敗
  • 事務的可能結果有三種:
    • 事務成功,沒有取消也沒有因為問題終結
      • 如果事務子流程是成功的,就會使用外出順序流繼續執行
      • 如果流程后來拋出了一個補償事件,成功的事務可能被補償
      • 和普通內嵌子流程一樣,事務可能在成功后,使用中間補償事件進行補償
    • 事務取消,流程到達取消結束事件
      • 所有流程都會終結和刪除,觸發補償的一個單獨的流程,會通過取消邊界事件繼續執行
      • 在補償完成之后,事務子流程會使用取消邊界事務的外出順序流向下執行
    • 事務被問題結束,拋出一個錯誤事件而且沒有在事務子流程中捕獲(如果錯誤被事務子流程的邊界事件處理了,也會這樣應用)
      • 不會執行補償
  • 事務三種不同的結果:
    在這里插入圖片描述
  • BPMN事務與ACID(技術)事務的關系: BPMN事務子流程與技術(ACID)事務不能互相混淆,BPMN事務子流程不是技術(ACID)事務領域的
  • BPMN事務和技術事務有以下不同點:
    • ACID事務一般是短期的.BPMN事務可能持續幾小時,幾天,甚至幾個月才能完成:
      • 考慮事務中包含的節點可能有用戶任務,一般人員響應的時間比應用時間要長
      • 在其他情況下,bpmn事務可能要等待發生一些事務事件,例如要根據某種次序執行
      • 這種操作通常要相比更新數據庫的一條數據,或把一條信息保存到事務性隊列中,消耗更長的時間來完成
    • BPMN事務一般要跨越多個ACID事務,因為不能在整個業務節點的過程中保持一個技術性的事務
    • BPMN事務會跨越多個ACID事務,所以會喪失ACID的特性:
      • 比如,在上述例子中,假設預訂旅店和刷信用卡操作在單獨的ACID事務中執行,假設預定旅店節點已經成功了
      • 現在處於一個中間不穩定狀態,因為我們預定了酒店,但是還沒有刷信用卡
      • 在一個ACID事務中,要依次執行不同的操作,也會有一個中間不穩定狀態
      • 不同的是,這個中間狀態對事務的外部是可見的.比如,如果通過外部預定服務進行了預定,其他使用相同預定服務的部分就可以看到旅店被預定了.這意味着實現業務事務時,我們完全失去了隔離屬性(放棄隔離性,可以為ACID事務獲得更高的並發,是可以完全控制,中間不穩定狀態也只持續很短的時間)
    • BPMN業務事務也不能使用通常的方式回滾:
      • BPMN事務跨越了多個事務,BPMN事務取消時一些ACID事務可能已經提交了.這時不能被回滾
  • BPMN事務運行時間很長,缺乏隔離性和回滾機制都需要被區別對待:
    • 使用補償執行回滾:
      • 如果事務范圍拋出了取消事件,會影響已經執行成功的節點,並使用補償處理器執行補償
    • 隔離性的缺乏通常使用特定領域的解決方法來解決:
      • 在上面的例子中,一個旅店房間可能會展示給第二個客戶,在我們確認第一個客戶付費之前.雖然這可能與業務預期不符,預定服務可能選擇允許一些過度的預約
    • 事務會因為風險而中斷,服務必須處理這種情況:
      • 已經預定了旅店,但是一直沒有付款的情況(因為事務被中斷了),這時預定服務需要選擇一個策略,在旅店房間預定超過最大允許時間后,如果還沒有付款,預定就會取消
  • 綜上所述,ACID處理的是通常問題:回滾,隔離級別和啟發式結果,在實現業務事務時,需要找到特定領域的解決方案來處理這些問題
  • BPMN事務目前的限制:
    • BPMN規范要求流程引擎能根據底層事務的協議處理事件:
      • 比如如果底層協議觸發了取消事件,事務就會取消
  • ACID事務頂層的一致性和優化並發:
    • BPMN事務保證一致性:
      • 要么所有節點都成功
      • 一些節點成功,對其他成功的節點進行補償
      • 無論哪種方式,都會有一致性的結果
      • 要討論一些activiti內部的情況BPMN事務的一致性模型是疊加在流程的一致性模型之上的
    • Activiti執行流程是事務性的,並發使用了樂觀鎖.在Activiti中,BPMN錯誤,取消和補償事件都建立在同樣的ACID事務與樂觀鎖之上:
      • 取消結束事件只能觸發它實際到達的補償
      • 如果之前服務任務拋出了未聲明的異常
      • 補償處理器的效果無法提交,如果底層的acid事務的參與者把事務設置成必須回滾.
      • 當兩個並發流程到達了取消結束事件
      • 可能會觸發兩次補償,並因為樂觀鎖異常失敗
      • 說明Activiti中實現BPMN事務時,相同的規則也作用域普通的流程和子流程
      • 為了保證一致性,重要的是使用一種方式考慮實現樂觀事務性的執行模型
圖形標記
  • 事務子流程顯示為內嵌子流程, 使用雙線邊框
    在這里插入圖片描述
XML內容
  • 事務子流程使用transaction標簽
<transaction id="myTransaction" >
        ...
</transaction>
實例

在這里插入圖片描述

調用活動(子流程)

描述
  • BPMN 2.0區分了普通子流程(內嵌子流程)和調用節點:
    • 相同點: 當流程抵達節點時兩者都會調用子流程
    • 不同點:
      • 調用節點引用流程定義外部的一個流程
      • 子流程會內嵌到原始的流程定義中
      • 使用調用節點的主要場景: 需要重用流程定義,這個流程定義需要被很多其他流程定義調用
  • 當流程執行到調用節點,會創建一個新分支,是到達調用節點的流程的分支
  • 這個分支會用來執行子流程,默認創建並行子流程,就像一個普通的流程
  • 上級流程會等待子流程完成,然后才會繼續向下執行
圖形標記
  • 調用節點顯示與子流程相同,但是粗邊框(無論是折疊和展開的). 根據不同的建模工具,調用節點也可以展開,但是顯示為折疊的子流程
    在這里插入圖片描述
XML內容
<callActivity id="callCheckCreditProcess" name="Check credit" calledElement="checkCreditProcess" />
  • 子流程的流程定義是在執行階段解析的,就是說子流程可以與調用的流程分開部署
傳遞變量
  • 可以把流程變量傳遞給子流程,反之亦然: 當它啟動的時候, 數據會復制給子流程,並在它結束的時候復制回主流程
<callActivity id="callSubProcess" calledElement="checkCreditProcess" >
  <extensionElements>
          <activiti:in source="someVariableInMainProcess" target="nameOfVariableInSubProcess" />
          <activiti:out source="someVariableInSubProcss" target="nameOfVariableInMainProcess" />
  </extensionElements>
</callActivity>

這里使用Activiti擴展來簡化BPMN標准元素調用dataInputAssociationdataOutputAssociation, 只在使用BPMN 2.0標准方式聲明流程變量有效

  • 也可以使用表達式:
<callActivity id="callSubProcess" calledElement="checkCreditProcess" >
        <extensionElements>
          <activiti:in sourceExpression="${x+5}"" target="y" />
          <activiti:out source="${y+5}" target="z" />
        </extensionElements>
</callActivity>
z = y + 5 = x + 5 + 5
實例
  • 訂單處理流程圖:先判斷客戶端信用,檢查信用階段設計成調用節點
    在這里插入圖片描述
  • 流程XML:
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="receiveOrder" />

<manualTask id="receiveOrder" name="Receive Order" />
<sequenceFlow id="flow2" sourceRef="receiveOrder" targetRef="callCheckCreditProcess" />

<callActivity id="callCheckCreditProcess" name="Check credit" calledElement="checkCreditProcess" />
<sequenceFlow id="flow3" sourceRef="callCheckCreditProcess" targetRef="prepareAndShipTask" />

<userTask id="prepareAndShipTask" name="Prepare and Ship" />
<sequenceFlow id="flow4" sourceRef="prepareAndShipTask" targetRef="end" />

<endEvent id="end" />
  • 子流程:
    在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM