> 文章列表 > Activiti7 工作流非原流程终止

Activiti7 工作流非原流程终止

Activiti7 工作流非原流程终止

背景

Activiti7 工作流非原流程终止
正常工作流,需要经过 node1、node2 才能结束。
现在要求已经开启的流程,目前停留在 node1,可以提前终止。

方案

一般根据实际需要,可以有几种做法:

  1. 新绘制流程图,新增 node1 结束的流程分支,替换原流程
  2. SQL 的方式,将该流程的数据,手动修改为终止的状态
  3. 代码动态修改流程模型,并使其流转只流向终止状态

下面分析一下这些方式的应用场景及优缺点。

新绘制流程图

新流程图

Activiti7 工作流非原流程终止

替换原流程图

UPDATE ACT_GE_BYTEARRAY SET BYTES_ = '新流程的对应值' WHERE _ID = xxx AND NAME_ = 'xxxxx.bpmn';
## 以下根据情况可选,在使用 activiti5 时有碰到
UPDATE ACT_GE_BYTEARRAY SET BYTES_ = '新流程的对应值' WHERE _ID = xxx AND NAME_ = 'xxx.png';
UPDATE ACT_GE_BYTEARRAY SET BYTES_ = '新流程的对应值' WHERE _ID = xxx AND NAME_ = 'source';
UPDATE ACT_GE_BYTEARRAY SET BYTES_ = '新流程的对应值' WHERE _ID = xxx AND NAME_ = 'source-extra';

后续根据条件,正确提交即可,可以正常流转。

优缺点

  • 优点
    • 新的流程分支可以从流程图上体现,一目了然;
    • 符合工作流的生命周期,正常应用工作流的监听器
    • 全局应用
  • 缺点
    • 修改工作流比较麻烦
    • 如果改动比较多,而且部分流程已经过了 node1 的话,可能会导致实时绘制流程报错。
    • 需要注意新老代码层面的兼容性(前提数据库唯一,但代码蓝绿发布)

应用场景

改动是全局的;
工作流模型改动有良好的版本管理和上线流程;
流程图需要体现这个分支流程(是正常业务应该关心的流转)

SQL修改工作流数据

DELETE FROM act_ru_task  WHERE ID_ = 'xxxx';
DELETE FROM act_ru_variable  WHERE PROC_INST_ID_ = 'xxxx';
DELETE FROM act_ru_execution WHERE ID_ = 'xxxx';
UPDATE act_hi_taskinst SET END_TIME_ = '2023-02-20 21:57:47.033000', DURATION_= 4180506 WHERE ID_ = 'xxxx';
UPDATE act_hi_procinstSET END_TIME_ = '2023-02-20 21:57:47.033000', DURATION_= 4180506, END_ACT_ID_ = 'endevent_oc' WHERE PROC_INST_ID_ = 'xxxx';

优缺点

  • 优点
    • 一次性,不用开发临时性代码
  • 缺点
    • SQL 改动风险高
    • 无法使用工作流层面的监听器
    • 如果存在业务数据修复,需要同时处理

应用场景

一次性流程关闭,无业务数据修复

代码动态修改流程模型

    /*** 提前终止业务流程实例,适用场景:当前任务节点没有对应的流程结束节点(业务变更导致需要终止流程)*/public void terminateProcessByBusinessKey(String businessKey) {taskService.createTaskQuery().processInstanceBusinessKey(businessKey).list().forEach(task -> terminateProcessByTask(task.getId(), task));}private void terminateProcessByTask(String taskId, Task task) {if (Objects.isNull(task)) {log.warn("流程任务实例不存在. taskId: {}", taskId);return;}BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());EndEvent endEvent = bpmnModel.getMainProcess().findFlowElementsOfType(EndEvent.class).get(0);FlowNode currentNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(task.getTaskDefinitionKey());List<SequenceFlow> orignOutgoingFlows = currentNode.getOutgoingFlows();SequenceFlow endFlow = new SequenceFlow();endFlow.setId("flow_to_temp_end");endFlow.setSourceFlowElement(currentNode);endFlow.setTargetFlowElement(endEvent);// 将当前节点的出向分支替换为流向 flow_to_temp_endcurrentNode.setOutgoingFlows(Lists.newArrayList(endFlow));taskService.complete(taskId);// 流转完恢复currentNode.setOutgoingFlows(orignOutgoingFlows);log.info("非正常方式完成流程. taskId: {},procDefKey: {},caseNo:{}", taskId, bpmnModel.getMainProcess().getId(), task.getBusinessKey());}

图例:Activiti7 工作流非原流程终止

优缺点

  • 优点
    • 通用的非正常关闭逻辑,不受限于某个节点
    • 可以应用工作流的生命周期,不影响事件触发或监听器
    • 可以便于处理业务数据的非正常结束
  • 缺点
    • 模型的改动是全局的,注意并发
    • 无法体现在流程图上
    • 实时流程图的生成会有影响

应用场景

  • 不仅限于一个节点的流程关闭
  • 业务不强要求流程关闭的分支体现在图上
  • 短期方案,逐步替换为正常流程