如何从与指定状态关联的任务节点重启Workflow工作流
工作流从指定历史状态重启的实现方案
核心结论:正常业务场景下你不需要重复调用runtimeService.startProcessInstanceByKey启动新流程,已启动的流程在进入IN_REVIEW关联的用户任务节点后会自动暂停等待,直接操作原有流程实例即可完成后续审批。
具体实现步骤
1. 启动流程时绑定业务主键
调用startProcessInstanceByKey时将实体ID作为业务主键传入,方便后续通过实体ID快速关联到对应的流程实例:
public void startProcess(MyEntity myEntity) { Map<String, Object> variables = new HashMap<>(); variables.put("entityId", myEntity.getId()); // 第二个参数为业务主键,和实体ID一一绑定 runtimeService.startProcessInstanceByKey("entityReview", myEntity.getId(), variables); }
2. 修正任务操作逻辑
你现有代码中直接将实体ID作为任务ID传入taskService.complete是错误的,任务ID和实体ID是两个完全不同的字段,需要先通过业务主键查询到当前待处理的任务:
首先封装通用的任务查询方法:
private Task getCurrentPendingTask(String entityId) { return taskService.createTaskQuery() .processInstanceBusinessKey(entityId) .active() .singleResult(); }
之后修改你的审核、批准、丢弃方法,以批准方法为例:
public void updateOnApprove(final MyEntity myEntity) { Task pendingTask = getCurrentPendingTask(myEntity.getId()); if (pendingTask == null) { throw new IllegalStateException("该实体无待处理的审核任务,请检查状态"); } Map<String, Object> variables = new HashMap<>(); variables.put("approved", true); taskService.complete(pendingTask.getId(), variables); }
其余updateOnReview、updateOnDiscard方法按照同样逻辑修改即可。
3. 异常场景下的指定节点重启方案
如果因为系统故障、数据异常等原因导致原有流程实例被销毁,需要从IN_REVIEW状态对应的节点重启流程,不要使用startProcessInstanceByKey,改用以下方式指定启动节点:
public void restartProcessFromReviewNode(MyEntity myEntity) { Map<String, Object> variables = new HashMap<>(); variables.put("entityId", myEntity.getId()); variables.put("review", true); runtimeService.createProcessInstanceByKey("entityReview") .businessKey(myEntity.getId()) .setVariables(variables) // 此处替换为你BPMN定义文件中IN_REVIEW状态对应的用户任务节点ID .startBeforeActivity("review_user_task_id") .execute(); }
注意事项
- 你现有代码中
getStauts拼写错误,应改为getStatus,字符串比较不要用==,改用equals方法避免空指针和判断错误 JavaDelegate类型的节点是自动执行的,不能作为等待用户操作的停留节点,IN_REVIEW状态对应的停留节点必须定义为用户任务(User Task)类型
内容的提问来源于stack exchange,提问作者j3d
相关产品推荐
相关产品推荐

