詳解Java EE工作流管理系統jBPM的FORK中節點同步功能
51CTO一直都關注Java EE工作流管理系統jBPM,在Java EE工作流管理系統jBPM中除功能節點(指START-STATE,END-State,Fork,Join,Decision)外,業務邏輯全放在NODE節點的ACTION中來實現。本文將詳解Java EE工作流管理系統jBPM的FORK中節點同步功能。
- public class DemoActionHandler implements ActionHandler {
- Java代碼
- /**
- * 簡單的ACTIONHANDLER DEMO
- */
- private static final long serialVersionUID = 1L;
- @SuppressWarnings("unchecked")
- @Override
- public void execute(ExecutionContext executionContext) throws Exception {
- Node node = executionContext.getNode();
- System.out.print(executionContext.getProcessInstance().getId());
- System.out.println("--[" + node.getName() + "] ["
- + new java.util.Date()+"]");
- ContextInstance cxtInstance = executionContext.getProcessInstance()
- .getContextInstance();
- try {
- Date date = new Date();
- Date startDate = (Date) cxtInstance.getVariable("STARTDATE");
- System.out.println("執行到此節點共用時:" + ""
- + (date.getTime() - startDate.getTime()));
- } catch (Exception e) {
- e.printStackTrace();
- }
- Thread.sleep(6000);
- node.leave(executionContext);
- }
- }
我寫了一個簡單的流程,串行的,不包含分支,只包含開始,結束,NODE三種類型的節點。將流程發布,創建實例 ,在實例啟動后用輪詢的方式查詢跟蹤token所在的位置(如果有分支的情況下可能需要考慮子token的情況),發現個流程的監控結果只有兩個結點:START和END,這是為什么呢,首先想到的是流程實例的狀態并沒有實時的保存或是說持久化到數據庫中去。
再結合自己的程序想了一下,程序中的節點全部是NODE類型的自動節點,流程在執行的時候,會直到一個等待節點才將流程實例持久化到數據庫中。但如果將NODE節點的async(異步執行)屬性設置的true,流程會在執行到該節點時,會啟動一個線程來執行NODE的ACTIONHANDLER,而TOKEN本身會掛起,等待執行完畢的消息,事務因此也將由一個被分裂為兩個獨立的事務.也就是說,原來從開始執行到等待狀態為止的一個事務被異步節點分了成多個事務,流程會在執行異步節點的ACTIONHANDLER時將事務提交,流程實例的狀態也就會持久化到數據庫中去。
于是加上
- Java代碼
- node.setAsync(true);
接著測試有分支的情況,又發現fork下的節點是依次執行的,查了資料,有如下的說法
引用
fork的底層其實是依次調用各個transition,而不是真正意義的同步,如果需要同步,請參考JBPM異步設置
于是把FORK節點的async屬性也設置成了true,測試后發現還是不行。按照上面的說法,fork在執行各個分支的時候,采用了類似遍歷的方式調用各個分支,但不至于非得執行完成一個分支后再執行另一個分支。無奈放下了,開始查找資料,這部分工作也是因此擱淺了將近一天的時間。晚上在家查閱資料的時候,發現有人提起了JobExecutor的線程個數,我覺得有可能這個的原因。翻下源碼,找了個API試驗一下
- Java代碼
- jobExecutor = jbpmConfiguration.getJobExecutor();
- jobExecutor.setNbrOfThreads(5);
- jobExecutor.start();
結果喜劇了,我驚喜的發現,fork下的節點竟然同步執行了(當然同步的執行也會有先后)。
雖然這本來就是fork節點的基本作用,但實際用起來的時候還是會遇到各種戰利品樣的問題。原因就在這里,如果不設置其線程數,JobExecutor默認啟動一個線程為工作,這樣就導致fork下的節點進入了隊列,結果就是串行執行了。
【編輯推薦】