`
jbpm-x
  • 浏览: 48680 次
  • 性别: Icon_minigender_2
  • 来自: 大连
社区版块
存档分类
最新评论

jbpm 并发子流程的解决方案与探讨

阅读更多

作者:JeffreyHsu

尽管jbpm非常强大,是目前最适合商业化的开源工作流引擎,可以开发出复杂的流程,但是特别遗憾的是并不支持并发子流程(multiple-subprocess)
有一次我需要做一个复杂的流程,主流程里要求同时启动多个并发执行的子流程,并且子流程的数目和启动的时间都不确定,当所有子流程都结束以后,主流程才继续执行。我们知道jbpm里有子流程的设定,有专门的节点ProcessState来处理,但是后来发现无论如何也实现不了多子流程并发执行,后来看其源码知道因为subprocess是作为ProcessState的一个属性,也就是说ProcessState只能包含一个subprocess的定义,并且最重要的是processInstance.getRootToken()和子流程相关的只有createSubProcessInstance, getSubProcessInstance, setSubProcessInstance三个方法,这意味着主流程的rootToken只能设置一个子流程,jbpm并不直接支持多子流程。
那么我们就必须用一个变通的方法来实现,“并发”很自然的让我们想到了fork,但是这里的fork不能搭配join来使用,具体原因,将在后面讨论。
下面先给出流程图:

state节点用来启动子流程(实际应用可以换成Task-Node),state进入fork后同时进入两个分支,一条去启动子流程,另一条回到自己,这样表面看来state没有动,而同时你又可以启动第2个,第3个……子流程,需要注意的是第2条子流程和第1个子流程并不处于同一级上,而比第一个子流程低一级,具体请看后面一张图就明白了,分解后的:

从图中我们可以看到后一个子流程的整棵树是前一个子流程的兄弟,但是在业务级上是并发的效果,已经实现我们前面的需求。

现在来说说为什么不能用join而直接用end,因为会产生一个问题,state3和sub process 2都到达了join以后,state2下面的fork就结束了,就会立刻越过join到达end,而sub process 1即使执行完毕到达了join却仍然在傻傻等待着他的兄弟分支也到达join(而实际上它已经自跑到end去了)一同结束,这样sub process 1就会永远停在join动弹不得,业务无法进行。

这是我的一个解决方案,但还有一个问题,虽然全部的子流程都能结束,主流程也能结束,但因为没有join,主流程的rootToken仍然停留在fork节点上。目前我尚不知如何解决,希望各位大家能提出其他更好的解决办法。
初学jbpm,水平有限,有不当之处还请高手斧正

最后附上demo代码供参考:

代码
  1.   
  2. import static org.junit.Assert.*;   
  3.   
  4. import org.jbpm.graph.def.ProcessDefinition;   
  5. import org.jbpm.graph.exe.ProcessInstance;   
  6. import org.jbpm.graph.exe.Token;   
  7. import org.jbpm.graph.node.ProcessState;   
  8. import org.junit.Before;   
  9. import org.junit.Test;   
  10.   
  11. public class MultiProcessTest {   
  12.     private ProcessDefinition superProcessDefinition;   
  13.   
  14.     private ProcessDefinition subProcessDefinition;   
  15.   
  16.     @Before   
  17.     public void setUp() throws Exception {   
  18.         superProcessDefinition = ProcessDefinition.parseXmlString(   
  19.                 "<process-definition name='super'>" +                
  20.                 "  <start-state name='start'>" +   
  21.                 "    <transition to='state' />" +   
  22.                 "  start-state>" +   
  23.                 "  <state name='state'>" +   
  24.                 "    <transition name='create sub' to='fork' />" +   
  25.                 "    <transition name='end' to='end' />" +   
  26.                 "  state>" +   
  27.                 "  <fork name='fork'>" +   
  28.                 "    <transition name='back' to='state' />" +   
  29.                 "    <transition name='go to sub' to='sub process' />" +   
  30.                 "  fork>" +   
  31.                 "  <process-state name='sub process'>" +   
  32.                 "    <sub-process name='sub' />" +   
  33.                 "    <transition to='end' />" +   
  34.                 "  process-state>" +   
  35.                 "  <end-state name='end' />" +   
  36.                 "process-definition>");   
  37.            
  38.         subProcessDefinition = ProcessDefinition.parseXmlString(   
  39.                 "<process-definition name='sub'>" +                          
  40.                 "  <start-state name='start'>"  +   
  41.                 "    <transition to='wait' />" +   
  42.                 "  start-state>" +                         
  43.                 "  <state name='wait'>" +   
  44.                 "    <transition to='end' />" +   
  45.                 "  state>" +              
  46.                 "  <end-state name='end' />" +   
  47.                 "process-definition>");   
  48.         ProcessState processState = (ProcessState) superProcessDefinition   
  49.                 .getNode("sub process");   
  50.         processState.setSubProcessDefinition(subProcessDefinition);   
  51.     }   
  52.   
  53.     @Test   
  54.     public void testMultiProcesses() {   
  55.         ProcessInstance pi = new ProcessInstance(superProcessDefinition);   
  56.   
  57.         // 启动一个主流程   
  58.         pi.signal();   
  59.         assertEquals("state", pi.getRootToken().getNode().getName());   
  60.   
  61.         // 进入分支,此处将进入子流程   
  62.         pi.signal("create sub");   
  63.         // 主流程token将停留在fork节点上   
  64.         assertEquals("fork", pi.getRootToken().getNode().getName());   
  65.   
  66.         // fork分为两支,其中一支的节点停留在ProcessState上   
  67.         Token subProcessToken1 = pi.getRootToken().getChild("go to sub");   
  68.         ProcessInstance subPi1 = subProcessToken1.getSubProcessInstance();   
  69.         assertEquals("wait", subPi1.getRootToken().getNode().getName());   
  70.   
  71.         // 另一支返回了state节点,实际上并没有返回,这个state节点不同于先前的state,它们并不在同一个path中   
  72.         Token stateToken1 = pi.getRootToken().getChild("back");   
  73.         assertEquals("state", stateToken1.getNode().getName());   
  74.            
  75.         // 再次进入fork,启动第二个子流程   
  76.         stateToken1.signal("create sub");   
  77.         ProcessInstance subPi2 = stateToken1.getChild("go to sub")   
  78.                 .getSubProcessInstance();   
  79.         // 虽然都是子流程,但它们并不相同,在逻辑上是属于并发的无关系的子流程   
  80.         assertFalse(subPi1.equals(subPi2));   
  81.         // 结束第二个子流程   
  82.         subPi2.signal();   
  83.         assertTrue(subPi2.hasEnded());   
  84.         assertFalse(pi.hasEnded());   
  85.   
  86.         // 结束第一个子流程,但主流程仍未结束   
  87.         subPi1.signal();   
  88.         assertTrue(subPi1.hasEnded());   
  89.         assertFalse(pi.hasEnded());   
  90.            
  91.         // 结束第二个子流程中的state,第一子流程的back分支结束,从而主流程也结束   
  92.         Token stateToken2 = stateToken1.getChild("back");   
  93.         assertEquals("state", stateToken2.getNode().getName());   
  94.         assertFalse(stateToken1.hasEnded());   
  95.         assertFalse(pi.hasEnded());   
  96.         stateToken2.signal("end");   
  97.            
  98.         assertTrue(stateToken1.hasEnded());   
  99.         assertTrue(subPi1.hasEnded());   
  100.         assertTrue(pi.getRootToken().getChild("back").hasEnded());   
  101.         assertTrue(pi.getRootToken().getChild("go to sub").hasEnded());   
  102.         // 主流程结束了   
  103.         assertTrue(pi.hasEnded());   
  104.         // 虽然主流程已经结束了,但是因为子流程没有join,所以其rootToken仍然停留在fork上   
  105.         assertEquals("fork", pi.getRootToken().getNode().getName());   
  106.         // 第二个子流程到达的end和主流程中的end并不是同一个节点   
  107.         assertTrue(!pi.getRootToken().getNode().equals(stateToken2.getNode()));   
  108.     }   
  109. }   
分享到:
评论
1 楼 爱之阡陌 2017-08-16  
                             

相关推荐

    【转载 见附件】纵观jBPM:从jBPM3到jBPM5以及Activiti5

    6. **使用场景** - 对比jBPM和Activiti5在实际项目中的应用,比如企业级BPM系统、工作流自动化解决方案等。 7. **性能和扩展性** - 分析两个框架在处理大量并发任务、复杂流程时的性能表现,以及如何进行扩展和定制...

    JBPM5.4 工作流例子

    总之,JBPM5.4为业务流程管理提供了全面的解决方案,其丰富的功能和良好的可扩展性使得它在企业级应用中广泛应用。通过深入研究提供的例子,你可以逐步掌握JBPM的工作流管理技术,为你的项目带来更高效、灵活的流程...

    中文文档JBPM

    在实际应用中,JBPM不仅可以用于处理业务流程,还可以与其他技术如Spring、JPA、Maven等集成,构建完整的业务解决方案。此外,JBPM还提供了可视化的流程设计器,使得流程设计更为直观和便捷。 总结起来,JBPM是一个...

    传智播客 jbpm 21讲 第3天(共4天)

    jbpm不仅支持BPMN 2.0标准,还整合了JPA、JPDL以及EJB等技术,为企业的业务流程自动化提供了一站式解决方案。 在传智播客的"jbpm 21讲"系列教程中,讲师孙文举深入浅出地讲解了jbpm的核心概念和实践应用。这个系列...

    JBPM案例详解(五)

    总的来说,"JBPM案例详解(五)"会通过实际的离职流程案例,帮助读者理解并掌握JBPM的流程设计、执行和监控能力,从而在实际工作中更有效地利用BPM解决方案解决类似的问题。对于想深入了解和应用JBPM的人来说,这是一...

    jBPM4工作流应用开发指南

    - 建立任务、事件、网关、子流程等各种流程元素,并定义它们之间的关系。 4. **流程部署** - 部署流程模型到jBPM4执行引擎,可以通过API或者Guvnor的web界面完成。 - 部署后,流程定义会存储在数据库中,可供...

    JBPM相关学习资料

    **JBPM相关学习资料** JBPM(Java Business Process Management)是一种开源的工作流管理系统,它提供了对业务流程...文档"jbpm常见异常解决方案.doc"应包含更具体的故障排除步骤和案例,可作为日常开发中的实用指南。

    jbpm3.rar_bpm_bpm jbpm_jbpm3_workflow_workflow process bpm

    综上所述,jbpm3是BPM领域的强大工具,提供了一整套工作流解决方案。理解并熟练使用jbpm3,不仅可以提升企业的业务流程效率,还能促进软件开发的标准化和规范化。通过详细阅读提供的文档和资源,开发者可以深入掌握...

    jbpm exercise3

    jbpm是一个开源的工作流管理系统,它提供了全面的BPM(Business Process Management)解决方案,包括业务流程建模、执行、监控以及优化。 在jbpm Exercise3中,我们可以期待学习以下几个核心知识点: 1. **jbpm...

    JBPM4学习笔记

    JBPM4基于Java技术,它提供了工作流程建模、执行和监控的一体化解决方案。它支持BPMN2.0标准,使得流程模型具有高度的可读性和可维护性。JBPM4的组件包括流程定义工具、执行引擎、持久化存储、工作流服务以及监控...

    工作流(JBPM)一些有用资料整合

    JBPM是一个开源的工作流和业务规则管理系统,它提供了完整的工作流解决方案,包括流程建模、执行、监控和管理。JBPM支持BPMN2.0标准,这使得业务流程可以以图形化的方式进行设计,易于理解和维护。同时,JBPM还集成...

    JBPM-v3.2-userguide

    jPDL套件包括了核心库、图形化流程设计器、控制台Web应用程序以及一系列辅助组件,如身份验证组件和任务执行器,共同构成了一个完整的BPM解决方案。 #### 1.3 图形化流程设计 jPDL图形化过程设计器允许用户通过直观...

    jBPM-4.0中文开发指南

    - **错误处理**: 遇到异常时的调试方法,以及常见错误的解决方案。 - **性能优化**: 提升jBPM在大规模流程部署下的运行效率。 ### 10. 社区与资源 - **官方文档**: 查阅jBPM官网获取最新的技术文档和更新信息。 - ...

    JBPM研究笔记

    JBPM(Java Business Process Management)是一个开源的工作流管理系统,它提供了全面的业务流程管理和工作流解决方案。这个系统的核心是基于模型驱动的架构,允许开发者通过图形化的方式设计、部署和执行复杂的业务...

    Spring3.1 + Hibernate4.2.1 + JBPM5.4 + Ehache整合例子

    Ehcache是一个广泛使用的Java缓存解决方案,提供内存和磁盘存储,以提高应用程序性能。在与Hibernate集成时,Ehcache作为二级缓存,可以存储数据库查询的结果,减少对数据库的访问,从而提高整体系统的响应速度和...

    BS结构下的OA流程可视化的设计与实现.doc

    未来,随着技术进步,如HTML5和WebGL的普及,可能会有更多轻量级且高效的解决方案出现,进一步增强OA流程可视化的体验。 总的来说,本文深入探讨了基于B/S结构的OA流程可视化的设计与实现,详细阐述了Java Applet...

    SSO__单点登录__微软解决方案__设计文档.rar

    3. **OAuth 和 OpenID Connect**:尽管这些协议不是微软独有的,但微软可能在其解决方案中集成了这些标准,以实现与其他平台和服务的互操作性。 4. **Azure Active Directory (Azure AD)**:微软的云身份管理服务,...

    四大国内外开源的java工作流程引擎,流程快速开发平台对比分析选型.docx

    最后,值得一提的是,随着低代码开发平台的发展,如文中的ccfast平台等,越来越多的解决方案也开始提供内置的工作流程管理功能,这为开发者提供了更加便捷的选择。对于那些希望减少开发工作量、加快项目交付速度的...

    OA项目源码

    深入研究这个“OA项目源码”,不仅能够提升对OA系统设计和jbpm工作流的理解,还能学习到实际项目中的最佳实践和常见问题解决方案。通过分析源码,开发者可以掌握一套完整的OA系统开发流程,为后续的项目提供宝贵的...

Global site tag (gtag.js) - Google Analytics