JBPM实践之并发子流程的实现
2009-02-08 22:44
316 查看
关于JBPM中并发子流程的实现方式,网上有很多的说法,但是好像每种办法都有这样那样的缺点,要么实现太复杂,要么就是会使Token无法继续流转。这里我介绍一种我的并发子流程的实现方式:使用TaskNode使任务并行的方式,模拟实现JBPM子流程的并发执行。
我先简单的介绍一下实现思路:
1、数据库中应该有至少三个已经发布过的流程定义(ProcessDefinition),发布的顺序无所谓,一个主流程两个子流程
2、我们在主流程中要实现并发子流程的环节放置TaskNode,设置create-tasks="false"、signal="last-wait"
3、我们想要实现几个子流程的并发就在第二步放置的TaskNode中放置几个Task,每个Task的名字都是要并发的子流程的名称
4、在TaskNode的Node-Enter action中,我们手动为每一个Task创建一个任务实例,同时我们取得Task的名字也就是要并发的子流程的名字,创建流程实例
5、为每个新创建的流程实例设置流程变量:TaskInstanceID表示创建当前子流程的那个主流程任务实例ID,并使子流程开始流转
6、子流程结束,取得流程变量TaskInstanceID,该流程变量TaskInstanceID是创建他的那个主流程的任务实例,得到该TaskInstance,并TaskInstance.end();
这个时候因为我们设置了TaskNode的Signal为"last-wait",所以当所有的子流程均结束的时候,主流程才会继续,这样我们也就实现了子流程的并发效果。很简单的一个思路实现起来也并不复杂。
首先让我们看一下主流程的流程定义:
下面是主流程的Node-EnterAction的代码:
再看其中一个子流程的定义:
下面是该子流程的ProcessEndAction:
思路很清楚,代码也很简单,按照这种方式我们可以让子流程实现所有Task能实现的功能。
我先简单的介绍一下实现思路:
1、数据库中应该有至少三个已经发布过的流程定义(ProcessDefinition),发布的顺序无所谓,一个主流程两个子流程
2、我们在主流程中要实现并发子流程的环节放置TaskNode,设置create-tasks="false"、signal="last-wait"
3、我们想要实现几个子流程的并发就在第二步放置的TaskNode中放置几个Task,每个Task的名字都是要并发的子流程的名称
4、在TaskNode的Node-Enter action中,我们手动为每一个Task创建一个任务实例,同时我们取得Task的名字也就是要并发的子流程的名字,创建流程实例
5、为每个新创建的流程实例设置流程变量:TaskInstanceID表示创建当前子流程的那个主流程任务实例ID,并使子流程开始流转
6、子流程结束,取得流程变量TaskInstanceID,该流程变量TaskInstanceID是创建他的那个主流程的任务实例,得到该TaskInstance,并TaskInstance.end();
这个时候因为我们设置了TaskNode的Signal为"last-wait",所以当所有的子流程均结束的时候,主流程才会继续,这样我们也就实现了子流程的并发效果。很简单的一个思路实现起来也并不复杂。
首先让我们看一下主流程的流程定义:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <process-definition xmlns="" name="super1"> 3 <start-state name="start-state1"> 4 <transition to="task-node1"></transition> 5 </start-state> 6 7 <task-node name="task-node1" create-tasks="false" signal="last-wait"> 8 <description> 9 我们要利用这个TaskNode实现并发子流程,create-tasks="true"是为了可以手动控制任务实例的创建,同时创建子流程, 10 signal="last-wait"是为了实现当所有子流程均已完成,主流程才能继续运行的效果 11 </description> 12 <task name="sub1"> 13 <description>要并发的子流程之一</description> 14 </task> 15 <task name="sub2"> 16 <description>要并发的子流程之二</description> 17 </task> 18 <event type="node-enter"> 19 <action name="NodeEnterAction" class="jbpmTest.bfzlc.action.NodeEnterAction"></action> 20 </event> 21 <transition to="end-state1"></transition> 22 </task-node> 23 24 <end-state name="end-state1"></end-state> 25 26 <event type="process-start"> 27 <script name="SuperProcessStart"> 28 System.out.println("主流程启动,并设置主流程ID"); 29 </script> 30 </event> 31 <event type="process-end"> 32 <script name="SuperProcessEnd"> 33 System.out.println("主流程结束"); 34 </script> 35 </event> 36 </process-definition> |
1 public class NodeEnterAction implements ActionHandler { 2 3 public void execute(ExecutionContext executionContext) throws Exception { 4 //取得本节点所有的Task 5 Set<Task> tasks = ((TaskNode)executionContext.getNode()).getTasks(); 6 7 TaskMgmtInstance tgmt = executionContext.getTaskMgmtInstance(); 8 9 for (Task task : tasks) { 10 //为每一个Task创建实例 11 TaskInstance taskInstance = tgmt.createTaskInstance(task, executionContext); 12 //业务Service 13 JbpmTestFacade jbpmTestFacade = ((JbpmTestFacade)SpringBeanUtil.getBean("jbpmTestFacade")); 14 //根据Task的名字,为每一个Task创建相应的子流程 15 ProcessInstance processInstance = jbpmTestFacade.createProcessInstance(task.getName()); 16 //设置创建这个子流程的流程实例ID 17 processInstance.getContextInstance().setVariable("TaskInstanceID", taskInstance.getId()); 18 //子流程开始流转 19 processInstance.signal(); 20 } 21 22 } 23 } |
1 <?xml version="1.0" encoding="UTF-8"?> 2 <process-definition xmlns="" name="sub1"> 3 <start-state name="start-state1"> 4 <transition to="Sub1Task"></transition> 5 </start-state> 6 7 <task-node name="Sub1Task"> 8 <task name="SubTask1"></task> 9 <transition to="end-state1"></transition> 10 </task-node> 11 12 <end-state name="end-state1"></end-state> 13 14 <event type="process-start"> 15 <script name="ProcessStartScript"> 16 System.out.println("-------------------sub1流程启动------------------------------"); 17 </script> 18 </event> 19 20 <event type="process-end"> 21 <action name="SubProcessEndAction" class="jbpmTest.bfzlc.action.SubProcessEndAction"></action> 22 </event> 23 </process-definition> 24 |
1 public class SubProcessEndAction implements ActionHandler { 2 3 public void execute(ExecutionContext executionContext) throws Exception { 4 System.out.println(executionContext.getProcessDefinition().getName()+"结束 "); 5 //得到创建当前子流程的那个TaskInstanceID 6 String taskInstanceID = executionContext.getContextInstance().getVariable("TaskInstanceID").toString(); 7 8 //业务Service 9 JbpmTestFacade jbpmTestFacade = ((JbpmTestFacade)SpringBeanUtil.getBean("jbpmTestFacade")); 10 //取得创建当前子流程的那个主流程taskInstance 11 TaskInstance taskInstance = jbpmTestFacade.geTaskInstance(Long.valueOf(taskInstanceID)); 12 taskInstance.end(); 13 } 14 15 } |
相关文章推荐
- JBPM实践之:并发子流程的实现
- 并发编程实践四:实现正确和高效的锁
- 使用NoSQL实现高并发CRM系统实践(源代码+解析)
- JBPM4.4 实现并发(fork -join)和事件监听(event-Listenner) 实现会签功能
- Linux下的socket编程实践(九) epoll实现高并发的原理及其使用
- jbpm 并发子流程的解决方案与探讨
- 使用NoSQL实现高并发CRM系统实践(源代码+解析)
- 使用NoSQL实现高并发CRM系统实践(源代码+解析)
- Linux下的socket编程实践(九) epoll实现高并发的原理及其使用
- 读Java并发编程实践中,向已有线程安全类添加功能--客户端加锁实现示例
- Python并发实践_02_通过yield实现协程
- jfinal 实现注解参数拦截实践
- JAVA Executor实现并发线程
- 项目实践与用OpenGL实现OBJ模型文件的读入
- NHibernate3.2+Asp.net MVC3+Extjs 4.0.2项目实践(六):Extjs Grid,Window,Form实现增删改操作
- Linux下突破限制实现高并发量服务器
- 一个轻量级Actor并发框架的c++实现, libgsc(Game Server Communication Library)(一)
- 【大型网站技术实践】初级篇:海量图片的分布式存储设计与实现
- golang 实现并发计算文件数量
- 高并发之限流算法及实现