别光看API了!聊聊SpringBoot集成Activiti后,那二十多张表到底都是干嘛的?
当你第一次在SpringBoot项目中集成Activiti工作流引擎,启动应用后看到数据库里突然多出的二十多张表,是否感到一头雾水?这些以act_re_、act_ru_、act_hi_、act_ge_开头的表究竟存储了什么数据?本文将带你深入Activiti的数据库设计哲学,通过真实场景解析每类表的核心作用,并教你如何直接查询数据库来辅助流程调试和问题排查。
1. Activiti表结构设计哲学:四大前缀解析
Activiti的表命名遵循严格的语义化规则,每个前缀代表特定的数据生命周期阶段:
1.1 静态资源表(act_re_*)
RE代表Repository,存储永远不会改变的流程定义和静态资源。核心表包括:
- act_re_procdef:流程定义表,存储部署的BPMN流程定义信息
- act_re_deployment:部署信息表,记录每次部署的元数据
- act_re_model:流程模型表,保存通过设计器创建的模型数据
-- 查询已部署的流程定义 SELECT ID_ AS 定义ID, NAME_ AS 流程名称, KEY_ AS 流程KEY, VERSION_ AS 版本 FROM act_re_procdef;1.2 运行时数据表(act_ru_*)
RU代表Runtime,存储流程运行时的动态数据,这些表会随着流程推进不断变化:
| 表名 | 存储内容 | 生命周期 |
|---|---|---|
| act_ru_execution | 流程执行实例 | 流程启动到结束 |
| act_ru_task | 当前任务节点 | 任务创建到完成 |
| act_ru_variable | 流程变量 | 随流程实例存在 |
提示:当流程出现卡顿时,首先检查
act_ru_task表确认当前待办任务状态
1.3 历史数据表(act_hi_*)
HI代表History,记录已完成流程的历史数据,需配置history-level启用:
- act_hi_procinst:历史流程实例
- act_hi_taskinst:历史任务记录
- act_hi_varinst:历史变量变更
// 配置示例:开启完整历史记录 spring: activiti: history-level: full1.4 通用数据表(act_ge_*)
GE代表General,存储引擎所需的通用数据:
- act_ge_bytearray:存储流程定义的BPMN和PNG文件二进制
- act_ge_property:系统属性表(如schema版本)
2. 全生命周期数据追踪:从启动到归档
2.1 流程部署阶段
当执行部署操作时,数据流向如下:
act_re_deployment记录部署元信息act_re_procdef新增流程定义记录act_ge_bytearray存储BPMN和PNG文件
-- 查看最新部署的流程资源 SELECT RESOURCE_NAME_ AS 资源名称, BYTES_ AS 内容 FROM act_ge_bytearray WHERE DEPLOYMENT_ID_ = (SELECT MAX(ID_) FROM act_re_deployment);2.2 流程实例运行阶段
流程启动后会产生运行时数据:
act_ru_execution生成执行实例记录act_ru_task创建当前待办任务act_ru_variable保存流程变量
// 启动流程时附加业务键(BusinessKey) ProcessInstance instance = runtimeService.startProcessInstanceByKey( "leaveProcess", "BUSINESS_KEY_123" );2.3 流程历史归档阶段
任务完成后,数据从运行时表迁移到历史表:
act_ru_task记录转移到act_hi_taskinst- 流程变量从
act_ru_variable转移到act_hi_varinst - 整个流程实例信息写入
act_hi_procinst
3. 实战排查:常见问题数据库查询方案
3.1 流程卡住怎么办?
-- 查询当前所有运行中的任务 SELECT T.ID_ AS 任务ID, T.NAME_ AS 任务名称, T.ASSIGNEE_ AS 处理人, P.NAME_ AS 流程名称, P.VERSION_ AS 流程版本 FROM act_ru_task T JOIN act_re_procdef P ON T.PROC_DEF_ID_ = P.ID_;3.2 如何追踪用户历史审批?
-- 查询指定用户完成的所有任务 SELECT T.ID_ AS 任务ID, T.NAME_ AS 任务名称, T.START_TIME_ AS 开始时间, T.END_TIME_ AS 完成时间, P.NAME_ AS 流程名称, P.BUSINESS_KEY_ AS 业务ID FROM act_hi_taskinst T JOIN act_hi_procinst P ON T.PROC_INST_ID_ = P.ID_ WHERE T.ASSIGNEE_ = 'user1' AND T.END_TIME_ IS NOT NULL ORDER BY T.END_TIME_ DESC;3.3 流程版本更新后老数据如何处理?
Activiti采用多版本共存策略:
- 新部署的流程会产生新版本的
act_re_procdef记录 - 已运行的流程实例继续使用原版本定义
- 可通过
runtimeService.updateBusinessKey()迁移业务关联
// 迁移业务键到新流程版本 runtimeService.updateBusinessKey( oldProcessInstance.getId(), "NEW_BUSINESS_KEY" );4. 高级技巧:自定义扩展与性能优化
4.1 历史数据归档策略
对于高频使用的系统,建议配置历史数据自动清理:
# 设置历史数据保留30天 activiti.history.cleanup.enabled=true activiti.history.cleanup.schedule=0 0 1 * * ? # 每天凌晨1点执行 activiti.history.time-to-live=P30D4.2 自定义表前缀
在SpringBoot配置中可修改默认表前缀:
spring: activiti: database-table-prefix: custom_act_4.3 关键表索引优化
为提高查询效率,建议添加以下索引:
-- 为历史任务表添加复合索引 CREATE INDEX idx_hi_task_procinst ON act_hi_taskinst(PROC_INST_ID_, END_TIME_); -- 运行时任务表Assignee索引 CREATE INDEX idx_ru_task_assignee ON act_ru_task(ASSIGNEE_);在实际项目中,当流程出现异常时,直接查询数据库往往比调试API更高效。掌握这些表结构细节后,你可以像运维DBA一样精准定位流程问题。最近在处理一个审批超时案例时,正是通过分析act_ru_task和act_ru_execution表的关联关系,发现是网关条件配置错误导致的分支卡死。