【Activiti】activiti 手動回退一個結束的流程


【Activiti】activiti 手動回退一個結束的流程

1. 引言

最近有一個流程回退的任務,於是就上網搜,發現流程回退大都是針對沒有結束的流程回退到上一步,而且給出的方法大都如吻末給出的相關鏈接中操作方式,試了試好像都不太好使。
於是就參照着網上的方法,順帶看接口看源碼,試了試感覺總是不夠靈活,還容易出錯。
后來想了想,其實他流程所有的信息都存在了23張表中,每一步,無非就是改這些表信息,我抹清每一個審批動作他到底改變了那些表,我把這些表數據回滾不就好了。

2. 准備

  1. 首先我們需要先了解一下這23張表到底都是干什么的
  2. 我們要知道這些表是怎么變化的
    關於表變化,要把過程記錄下來太麻煩了,我就不一一走了,給出一個參考鏈接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,可以參照源碼中搬過來稍微改改就好了

相關鏈接:

  1. activiti執行過程,表變化
    https://blog.csdn.net/ccdust/article/details/52600804
  2. Activiti從當前任務任意回退至已審批任務
    https://www.bbsmax.com/A/obzb4o4B5E/
  3. Activiti6實現自由跳轉
  4. https://segmentfault.com/a/1190000013952695
  5. Activiti6.0版本流程撤回、跳轉、回退等操作
    https://blog.csdn.net/lianjie_c/article/details/79242009


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM