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