【Activiti】activiti 手动回退一个结束的流程
【Activiti】activiti 手动回退一个结束的流程
1. 引言
最近有一个流程回退的任务,于是就上网搜,发现流程回退大都是针对没有结束的流程回退到上一步,而且给出的方法大都如吻末给出的相关链接中操作方式,试了试好像都不太好使。
于是就参照着网上的方法,顺带看接口看源码,试了试感觉总是不够灵活,还容易出错。
后来想了想,其实他流程所有的信息都存在了23张表中,每一步,无非就是改这些表信息,我抹清每一个审批动作他到底改变了那些表,我把这些表数据回滚不就好了。
2. 准备
- 首先我们需要先了解一下这23张表到底都是干什么的
- 我们要知道这些表是怎么变化的
关于表变化,要把过程记录下来太麻烦了,我就不一一走了,给出一个参考链接https://blog.csdn.net/ccdust/article/details/52600804
ACT_EVT_LOG
-- ACT_GE_* 通用数据, 用于不同场景下
ACT_GE_BYTEARRAY
ACT_GE_PROPERTY
-- ACT_HI_* history 历史数据,每一步操作,都会在这些相关表记录
ACT_HI_ACTINST
ACT_HI_ATTACHMENT
ACT_HI_COMMENT
ACT_HI_DETAIL
ACT_HI_IDENTITYLINK
ACT_HI_PROCINST
ACT_HI_TASKINST
ACT_HI_VARINST
--ACT_ID_* identity 身份信息
ACT_ID_GROUP
ACT_ID_INFO
ACT_ID_MEMBERSHIP
ACT_ID_USER
ACT_PROCDEF_INFO
--ACT_RE_* repository 流程相关表(流程部署、流程模型、流程定义)
ACT_RE_DEPLOYMENT
ACT_RE_MODEL
ACT_RE_PROCDEF
--ACT_RU_* runtime 流程运行时表,流程结束,这些表数据清空
ACT_RU_EVENT_SUBSCR
ACT_RU_EXECUTION
ACT_RU_IDENTITYLINK
ACT_RU_JOB
ACT_RU_TASK
ACT_RU_VARIABLE
-- 可能我们业务结合,还会自定义一些表,保存重要信息
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
3. 回退
建议先找一个备份库,直接用sql操作回退流程,找到每一步都的变化,直到成功,然后再在代码中实现。
我这里记录的是一个结束的流程回退,所以运行时表中已经没有数据了,得从历史表走起
3.1 先用sql试验回退activiti表
-- 1. 查询ACT_HI_TASKINST,返回历史中task数据
select * from ACT_HI_TASKINST where ID_=#{taskId};
--2. 创建一个ACT_RU_EXECUTION记录,每一个流程都有一个记录,流程结束清除,但EXECUTION没有历史表,所以自己创建
# 参照插入 select * from ACT_RU_EXECUTION;
insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_,IS_EVENT_SCOPE_, PARENT_ID_, SUPER_EXEC_, SUSPENSION_STATE_, CACHED_ENT_STATE_, TENANT_ID_, NAME_)
values (...);
-- 3. 将历史数据task添加至ACT_RU_TASK
# 参照插入 select * from ACT_RU_TASK;
insert into ACT_RU_TASK (ID_, REV_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_, DUE_DATE_, CATEGORY_, SUSPENSION_STATE_, TENANT_ID_, FORM_KEY_)
values ();
-- 4. 恢复当前任务相关处理人到ACT_RUN_IDENTITYLINK
select * from ACT_HI_IDENTITYLINK WHERE PROC_INST_ID_={} OR TASK_ID_={};
# 这里会返回一个list
# 参照插入 select * from ACT_RU_IDENTITYLINK;
insert into ACT_RU_IDENTITYLINK (ID_, REV_, TYPE_, USER_ID_, GROUP_ID_, TASK_ID_, PROC_INST_ID_, PROC_DEF_ID_)
values ();
-- 5. 添加运行时变量 ACT_RUN_VARIABLE
select * from ACT_HI_VARINST where EXECUTION_ID_={};
# 这里会返回一个list
# 参照插入 select * from ACT_RUN_VARIABLE;
insert into ACT_RU_VARIABLE (ID_, REV_, TYPE_, NAME_, PROC_INST_ID_, EXECUTION_ID_, TASK_ID_, BYTEARRAY_ID_, DOUBLE_, LONG_ , TEXT_, TEXT2_)
values ();
-- 至此数据已经恢复到待办中了,下一步还要回退已办中的数据哈
-- 6. 撤销已办
# 因为这是回退一个已经结束的流程,所以那个流程肯定会在已办列表里
# 看一下自己的已办是根据什么查询的对应修改相应数据
# 我这里是根据ACT_HI_TASKINST表endtime如果不为NULL,就到已办中去了
# 所以我只需要将这条记录中的endtime再改为NULL
select * from ACT_HI_TASKINST where ID_={};
update ACT_HI_TASKINST set END_TIME_={} where ID_={};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
3.2 代码实现回退activiti流程
代码中实现,按上边sql顺序写逻辑就好了
@Transactional
public void rollbackTask(String taskId){
ProcessEngine pe = ActivitiConfiguration.getProcessEngine();
logger.info("begin to rollback task: [{}]",taskId);
//1. select task
HistoricTaskInstance hstTask = pe.getHistoryService().createHistoricTaskInstanceQuery()
.taskId(taskId).singleResult();
if(hstTask == null){
throw new RuntimeException("task is not exists: "+ taskId);
}
//2. create a execution,SubExecutionEntity只是添加了一个构造器
ExecutionEntity execution = new SubExecutionEntity(
hstTask.getExecutionId(),
hstTask.getProcessInstanceId(),
hstTask.getProcessDefinitionId(),
hstTask.getTaskDefinitionKey());
logger.info("create a new run execution");
taskRollBackMapper.insertExecution(execution);
//3. insert task into ACT_RU_TASK
TaskEntity runTask = new TaskEntity();
runTask.setId(hstTask.getId());
runTask.setName(hstTask.getName());
runTask.setPriority(hstTask.getPriority());
runTask.setCreateTime(hstTask.getCreateTime());
runTask.setAssignee(hstTask.getAssignee());
runTask.setExecutionId(hstTask.getExecutionId());
runTask.setProcessInstanceId(hstTask.getProcessInstanceId());
runTask.setProcessDefinitionId(hstTask.getProcessDefinitionId());
runTask.setTaskDefinitionKey(hstTask.getTaskDefinitionKey());
logger.info("insert task[{}] into ACT_RU_TASK",taskId);
taskRollBackMapper.insertTask(runTask);
//4. insert task identitylink into ACT_RUN_IDENTITYLINK
List<HistoricIdentityLinkEntity> hstIdentityLinks= taskRollBackMapper
.selectHistoricIdentityLinksByProcessInstanceAndTaskId(hstTask.getProcessInstanceId(), hstTask.getId());
List<IdentityLinkEntity> identityLinkEntities = new ArrayList<>();
for (HistoricIdentityLinkEntity hstIdentityLink:hstIdentityLinks){
IdentityLinkEntity identityLink = new IdentityLinkEntity();
identityLink.setId(hstIdentityLink.getId());
identityLink.setType(hstIdentityLink.getType());
identityLink.setUserId(hstIdentityLink.getUserId());
identityLink.setTaskId(hstIdentityLink.getTaskId());
identityLink.setProcessInstanceId(hstIdentityLink.getProcessInstanceId());
identityLinkEntities.add(identityLink);
}
logger.info("bulk insert task identitylinks into ACT_RUN_IDENTITYLINK");
taskRollBackMapper.bulkInsertIdentityLink(identityLinkEntities);
// 5. insert variables into ACT_RU_VARIABLE
final List<HistoricVariableInstance> hstVariables = pe.getHistoryService().createHistoricVariableInstanceQuery()
.executionId(hstTask.getExecutionId()).list();
List<VariableInstanceEntity> variables = new ArrayList<>();
for (HistoricVariableInstance hstVariable:hstVariables){
VariableInstanceEntity variableInstance = VariableInstanceEntity
.create(hstVariable.getVariableName(), new StringType(100), hstVariable.getValue());
variableInstance.setId(hstVariable.getId());
variableInstance.setExecutionId(hstVariable.getProcessInstanceId());
variableInstance.setProcessInstanceId(hstVariable.getProcessInstanceId());
variableInstance.setTaskId(hstVariable.getTaskId());
variableInstance.setTextValue((String) hstVariable.getValue());
variables.add(variableInstance);
}
logger.info("bulk insert task variables into ACT_RU_VARIABLE");
taskRollBackMapper.bulkInsertVariableInstance(variables);
// 6. remove task from history record
HistoricTaskInstanceEntity hstTaskUpdate = new HistoricTaskInstanceEntity();
hstTaskUpdate.setId(hstTask.getId());
hstTaskUpdate.setProcessDefinitionId(hstTask.getProcessDefinitionId());
hstTaskUpdate.setTaskDefinitionKey(hstTask.getTaskDefinitionKey());
hstTaskUpdate.setProcessInstanceId(hstTask.getProcessInstanceId());
hstTaskUpdate.setExecutionId(hstTask.getExecutionId());
hstTaskUpdate.setName(hstTask.getName());
hstTaskUpdate.setAssignee(hstTask.getAssignee());
hstTaskUpdate.setStartTime(hstTask.getStartTime());
hstTaskUpdate.setClaimTime(hstTask.getClaimTime());
hstTaskUpdate.setEndTime(null);
hstTaskUpdate.setDueDate(hstTask.getDueDate());
hstTaskUpdate.setDeleteReason(hstTask.getDeleteReason());
hstTaskUpdate.setPriority(hstTask.getPriority());
logger.info("remove task from history record");
taskRollBackMapper.updateHistoricTaskInstance(hstTaskUpdate);
logger.info("rollback task: [{}] end",taskId);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
至于mapper.xml,可以参照源码中搬过来稍微改改就好了
相关链接:
- activiti执行过程,表变化
https://blog.csdn.net/ccdust/article/details/52600804 - Activiti从当前任务任意回退至已审批任务
https://www.bbsmax.com/A/obzb4o4B5E/ - Activiti6实现自由跳转
- https://segmentfault.com/a/1190000013952695
- Activiti6.0版本流程撤回、跳转、回退等操作
https://blog.csdn.net/lianjie_c/article/details/79242009
为人:谦逊、激情、博学、审问、慎思、明辨、 笃行
学问:纸上得来终觉浅,绝知此事要躬行
为事:工欲善其事,必先利其器。
态度:道阻且长,行则将至;行而不辍,未来可期
.....................................................................
------- 桃之夭夭,灼灼其华。之子于归,宜其室家。 ---------------
------- 桃之夭夭,有蕡其实。之子于归,宜其家室。 ---------------
------- 桃之夭夭,其叶蓁蓁。之子于归,宜其家人。 ---------------
=====================================================================
* 博客文章部分截图及内容来自于学习的书本及相应培训课程以及网络其他博客,仅做学习讨论之用,不做商业用途。
* 如有侵权,马上联系我,我立马删除对应链接。 * @author Alan -liu * @Email no008@foxmail.com
转载请标注出处! ✧*꧁一品堂.技术学习笔记꧂*✧. ---> https://www.cnblogs.com/ios9/
学问:纸上得来终觉浅,绝知此事要躬行
为事:工欲善其事,必先利其器。
态度:道阻且长,行则将至;行而不辍,未来可期
.....................................................................
------- 桃之夭夭,灼灼其华。之子于归,宜其室家。 ---------------
------- 桃之夭夭,有蕡其实。之子于归,宜其家室。 ---------------
------- 桃之夭夭,其叶蓁蓁。之子于归,宜其家人。 ---------------
=====================================================================
* 博客文章部分截图及内容来自于学习的书本及相应培训课程以及网络其他博客,仅做学习讨论之用,不做商业用途。
* 如有侵权,马上联系我,我立马删除对应链接。 * @author Alan -liu * @Email no008@foxmail.com
转载请标注出处! ✧*꧁一品堂.技术学习笔记꧂*✧. ---> https://www.cnblogs.com/ios9/