Camunda并行会签实战:从BPMN设计到数据库状态变化的完整追踪
Camunda并行会签实战:从BPMN设计到数据库状态变化的完整追踪
在复杂业务流程自动化领域,并行会签是一种常见但实现难度较高的模式。当三个部门主管需要同时审批一份采购申请时,传统串行审批会导致效率低下,而并行处理又面临状态同步的挑战。Camunda作为业界领先的开源流程引擎,其多实例任务特性为这类场景提供了优雅解决方案。
本文将带您深入Camunda引擎内部,通过直接观察数据库表变化,揭示并行会签的完整生命周期。不同于常规教程仅展示界面操作,我们将聚焦ACT_RU_TASK、ACT_RU_EXECUTION等核心表的实时变化,用数据库视角还原并行分支创建、任务完成、实例汇聚的全过程。这种"数据库探针"式分析方法,特别适合需要深度排查流程异常或优化性能的进阶开发者。
1. 并行会签的BPMN建模要点
实现有效并行会签的第一步是正确建模。在Camunda Modeler中创建包含多实例标记的用户任务时,关键要掌握三个配置维度:
集合型多实例配置参数
| 参数名 | 必填 | 作用 | 示例值 |
|---|---|---|---|
| collection | 是 | 参与者集合变量名 | assigneeList |
| elementVariable | 是 | 集合元素变量名 | assignee |
| completionCondition | 否 | 提前完成条件 | ${nrOfCompletedInstances/nrOfInstances >= 0.5} |
典型的Groovy脚本初始化示例:
def approvers = ['finance_mgr', 'tech_mgr', 'ops_mgr'] execution.setVariable("approverList", approvers)注意:集合变量必须在流程实例启动前初始化,否则会抛出NullValueException。推荐在启动事件或第一个任务配置执行监听器。
2. 运行时表结构深度解析
当流程实例运行到并行会签环节时,Camunda会在底层创建复杂的执行树结构。通过以下SQL可观察运行时状态:
核心运行时表字段说明
-- 查看任务实例状态 SELECT ID_, NAME_, ASSIGNEE_, SUSPENSION_STATE_, CASE SUSPENSION_STATE_ WHEN 1 THEN 'Active' WHEN 2 THEN 'Suspended' END AS STATE_DESC FROM ACT_RU_TASK WHERE PROC_INST_ID_ = '流程实例ID'; -- 查看执行流状态 SELECT ID_, ACT_ID_, IS_ACTIVE_, IS_SCOPE_, IS_CONCURRENT_, SEQUENCE_COUNTER_ FROM ACT_RU_EXECUTION WHERE PROC_INST_ID_ = '流程实例ID';当三个并行任务创建时,您会观察到:
ACT_RU_TASK表插入三条记录,ASSIGNEE_分别对应集合元素ACT_RU_EXECUTION表生成四条记录:- 1条父执行流(IS_SCOPE_=1)
- 3条子执行流(IS_CONCURRENT_=1)
3. 任务完成时的状态迁移追踪
每个会签任务完成时,数据库会发生连锁反应。以下实验演示user1完成审批时的变化:
步骤1:查询初始状态
-- 记录当前任务和执行流ID SELECT ID_ FROM ACT_RU_TASK WHERE ASSIGNEE_ = 'user1'; SELECT ID_ FROM ACT_RU_EXECUTION WHERE ACT_ID_ = 'parallel_approval';步骤2:完成任务后检查
-- 原任务消失 SELECT * FROM ACT_RU_TASK WHERE ID_ = '原任务ID'; -- 历史表新增记录 SELECT ACT_ID_, ACT_NAME_, ASSIGNEE_, END_TIME_ FROM ACT_HI_ACTINST WHERE PROC_INST_ID_ = '流程实例ID' ORDER BY START_TIME_ DESC LIMIT 1; -- 执行流计数器变化 SELECT SEQUENCE_COUNTER_ FROM ACT_RU_EXECUTION WHERE ID_ = '父执行流ID';典型现象包括:
ACT_RU_TASK中对应记录删除ACT_HI_ACTINST新增完成记录- 父执行流的
SEQUENCE_COUNTER_值递增
4. 汇聚网关的数据库表现
当最后一个并行任务完成时,引擎触发隐式汇聚。此时可观察到:
汇聚时的关键变化
- 所有子执行流被删除
- 父执行流的
IS_ACTIVE_变为0 - 历史表中生成完整的并行分支记录
- 流程变量同步到父作用域
验证SQL:
-- 检查执行流状态 SELECT ID_, IS_ACTIVE_, ACT_ID_ FROM ACT_RU_EXECUTION WHERE PROC_INST_ID_ = '流程实例ID'; -- 检查历史活动 SELECT ACT_ID_, ACT_INST_STATE_ FROM ACT_HI_ACTINST WHERE PROC_INST_ID_ = '流程实例ID' AND ACT_TYPE_ = 'multiInstanceBody';5. 异常场景排查指南
当并行会签出现异常时,建议按此顺序排查:
集合变量未初始化
- 检查
ACT_RU_VARIABLE表是否存在预期变量 - 验证Groovy脚本是否在正确节点执行
- 检查
任务卡在创建阶段
- 确认
ACT_RU_TASK有无预期记录 - 检查
ACT_RU_EXECUTION中子执行流是否正常
- 确认
汇聚失败
- 对比
nrOfCompletedInstances与nrOfInstances - 检查
completionCondition表达式语法
- 对比
性能问题
- 监控
SEQUENCE_COUNTER_增长趋势 - 检查历史表数据量是否过大
- 监控
-- 典型排查查询 SELECT VAR.NAME_, VAR.TEXT_, EXEC.ACT_ID_, EXEC.IS_ACTIVE_, TASK.NAME_, TASK.ASSIGNEE_ FROM ACT_RU_EXECUTION EXEC LEFT JOIN ACT_RU_VARIABLE VAR ON VAR.EXECUTION_ID_ = EXEC.ID_ LEFT JOIN ACT_RU_TASK TASK ON TASK.EXECUTION_ID_ = EXEC.ID_ WHERE EXEC.PROC_INST_ID_ = '异常实例ID';6. 高级调试技巧
对于需要深度调试的场景,可以启用Camunda的数据库日志:
配置日志级别
# log4j.properties log4j.logger.org.camunda.bpm.engine.persistence=DEBUG关键日志事件对应表变化
| 日志事件 | 涉及表变化 | 典型SQL观察语句 |
|---|---|---|
| 创建并行分支 | ACT_RU_EXECUTION新增记录 | SELECT * FROM ACT_RU_EXECUTION WHERE PARENT_ID_ = '父ID' |
| 完成任务 | ACT_HI_ACTINST更新 | SELECT END_TIME_ FROM ACT_HI_ACTINST WHERE ACT_ID_='任务ID' |
| 变量同步 | ACT_RU_VARIABLE值变化 | SELECT TEXT_ FROM ACT_RU_VARIABLE WHERE NAME_='nrOfInstances' |
在开发环境中,结合数据库监控工具如DBeaver的"数据变化跟踪"功能,可以实时捕捉表记录变化,比单纯依赖日志更直观。
