Activity並行網關和排他網關
說一說activiti中的排他網關和並行網關
activiti工作流中我們經常用到的網關有兩種:
1. Exclusive Gateway 排他網關
排他網關.png
排他網關(也叫異或(XOR)網關,或更技術性的叫法 基於數據的排他網關), 用來在流程中實現決策。 當流程執行到這個網關,所有外出順序流都會被處理一遍。 其中條件
解析為true的順序流(或者沒有設置條件,概念上在順序流上定義了一個‘true‘) 會被選
中,讓流程繼續運行。
註意這裏的外出順序流 與 BPMN 2.0 通常的概念是不同的。通常情況下,所有條件結果> 為true的順序流 都會被選中,以並行方式執行,但排他網關只會選擇一條順序流執行。
就是說,雖然多個順序流的條件結果為true, 那麽XML中的第一個順序流(也只有這一
條)會被選中,並用來繼續運行流程。 如果沒有選中任何順序流,會拋出一個異常
排他網關定義非常直接,在xml裏面就一句
<exclusiveGateway id="exclusiveGw" name="Exclusive Gateway" /><sequenceFlow id="flow2" sourceRef="exclusiveGw" targetRef="theTask1"> <conditionExpression xsi:type="tFormalExpression">${input == 1}</conditionExpression></sequenceFlow><sequenceFlow id="flow3" sourceRef="exclusiveGw" targetRef="theTask2"> <conditionExpression xsi:type="tFormalExpression">${input == 2}</conditionExpression></sequenceFlow><sequenceFlow id="flow4" sourceRef="exclusiveGw" targetRef="theTask3"> <conditionExpression xsi:type="tFormalExpression">${input == 3}</conditionExpression></sequenceFlow>
排他網關示意圖.png
上圖是使用activiti modeler在線設計時候的截圖
排他網關有點像java裏面 if ... else if ... 每一個分支線上都要指定一個條件,可以有多條分支線,分支線的的變量需要在網關之前就設置到流程變量中。
** 舉個栗子,可以在我上面圖裏面usertask這個節點添加一個執行監聽器 **
添加執行監聽器.png
添加執行監聽器.png
執行監聽器代碼
@Service("taskFinishedLicenser")@Transactional(propagation = Propagation.NOT_SUPPORTED)public class TaskFinishedLicenser implements ExecutionListener { private static final long serialVersionUID = 2105979050046650949L; @Override public void notify(DelegateExecution execution){ try{ //set global flow varible execution.getEngineServices().getRuntimeService().setVariableLocal(execution.getProcessInstanceId(),"input",1); }catch(Exception e){ execution.getEngineServices().getRuntimeService().setVariableLocal(execution.getProcessInstanceId(),"input",2); logger.error(e.getMessage()); } } }
設置了流程變量後,分支條件獲取的時候就可以讀取到變量了。
2. Parallel Gateway 並行網關
並行網關.png
網關也可以表示流程中的並發情況。最簡單的並發網關是 並行網關,它允許將流程分成
多條分支,也可以把多條分支 匯聚到一起。
並行網關的功能是基於進入和外出的順序流的:
分支: 並行後的所有外出順序流,為每個順序流都創建一個並發分支。
匯聚: 所有到達並行網關,在此等待的進入分支, 直到所有進入順序流的分支都到達以後, 流程就會通過匯聚網關。
註意,如果同一個並行網關有多個進入和多個外出順序流, 它就同時具有分支和匯聚功
能。這時,網關會先匯聚所有進入的順序流,然後再切分成多個並行分支。與其他網關的主要區別是,並行網關不會解析條件。 即使順序流中定義了條件,也會被忽略。
這裏需要強調的是,** 並行網關一定是成對出現的,有分支也要有匯聚 **
** 一個分支執行完畢後,需要等待其他分支全部執行完流程才會走到下一個節點 **
還有一個有意思的點是,流程開始執行後,點擊流程監控發現,執行到並行網關中間的節點時,當前執行節點是顯示在並行網關節點上,並不會顯示到中間具體的一個節點,所以activiti是把兩個並行節點間的所有任務節點,看作是一個事務。
並行網關.png
<startEvent id="theStart" /><sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" /><parallelGateway id="fork" /><sequenceFlow sourceRef="fork" targetRef="receivePayment" /><sequenceFlow sourceRef="fork" targetRef="shipOrder" /><userTask id="receivePayment" name="Receive Payment" /> <sequenceFlow sourceRef="receivePayment" targetRef="join" /><userTask id="shipOrder" name="Ship Order" /> <sequenceFlow sourceRef="shipOrder" targetRef="join" /><parallelGateway id="join" /><sequenceFlow sourceRef="join" targetRef="archiveOrder" /><userTask id="archiveOrder" name="Archive Order" /> <sequenceFlow sourceRef="archiveOrder" targetRef="theEnd" /><endEvent id="theEnd" />
Activity並行網關和排他網關