String processInstanceId = processInstanceExecution.getId(); // No parent execution == process instance id logger.debug("No parent execution found. Verifying if process instance {} can be stopped.", processInstanceId); // 找父实例 ExecutionEntity superExecution = processInstanceExecution.getSuperExecution(); SubProcessActivityBehavior subProcessActivityBehavior = null;
// copy variables before destroying the ended sub process instance (call activity) // 在销毁结束的子流程实例(调用活动)之前复制变量 if (superExecution != null) { // 存在父执行 FlowNode superExecutionElement = (FlowNode) superExecution.getCurrentFlowElement(); subProcessActivityBehavior = (SubProcessActivityBehavior) superExecutionElement.getBehavior(); try { //保存内嵌子流程的变量到库和执行实例execution subProcessActivityBehavior.completing(superExecution, processInstanceExecution); } catch (RuntimeException e) { logger.error("Error while completing sub process of execution {}", processInstanceExecution, e); throw e; } catch (Exception e) { logger.error("Error while completing sub process of execution {}", processInstanceExecution, e); thrownew ActivitiException("Error while completing sub process of execution " + processInstanceExecution, e); } } //获取当前存活的子执行数量 int activeExecutions = getNumberOfActiveChildExecutionsForProcessInstance(executionEntityManager, processInstanceId); if (activeExecutions == 0) { logger.debug("No active executions found. Ending process instance {} ", processInstanceId); // note the use of execution here vs processinstance execution for getting the flowelement //这里使用流程实例执行来获取流程元素(删除实例相关所有数据) executionEntityManager.deleteProcessInstanceExecutionEntity(processInstanceId, execution.getCurrentFlowElement() != null ? execution.getCurrentFlowElement().getId() : null, null, false, false); } else { logger.debug("Active executions found. Process instance {} will not be ended.", processInstanceId); }
Process process = ProcessDefinitionUtil.getProcess(processInstanceExecution.getProcessDefinitionId());
// Execute execution listeners for process end. // 执行结束监听器 if (CollectionUtil.isNotEmpty(process.getExecutionListeners())) { executeExecutionListeners(process, processInstanceExecution, ExecutionListener.EVENTNAME_END); }
// and trigger execution afterwards if doing a call activity if (superExecution != null) { superExecution.setSubProcessInstance(null); try { // 行为操作最终调用leave离开 subProcessActivityBehavior.completed(superExecution); } catch (RuntimeException e) { logger.error("Error while completing sub process of execution {}", rocessInstanceExecution, e); throw e; } catch (Exception e) { logger.error("Error while completing sub process of execution {}", processInstanceExecution, e); thrownew ActivitiException("Error while completing sub process of execution " + processInstanceExecution, e); } } }
protectedvoidhandleRegularExecution(){ ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager(); // There will be a parent execution (or else we would be in the process instance handling method) ExecutionEntity parentExecution = executionEntityManager.findById(execution.getParentId()); // If the execution is a scope, all the child executions must be deleted first. // 如果执行是父但非流程实例,则必须首先删除所有子执行。 if (execution.isScope()) { executionEntityManager.deleteChildExecutions(execution, null, false); } // Delete current execution logger.debug("Ending execution {}", execution.getId()); executionEntityManager.deleteExecutionAndRelatedData(execution, null, false); logger.debug("Parent execution found. Continuing process using execution {}", parentExecution.getId()); // 需要特别注意: 在多实例子流程中结束执行时; // When ending an execution in a multi instance subprocess , special care is needed if (isEndEventInMultiInstanceSubprocess(execution)) { //处理多实例子流程 handleMultiInstanceSubProcess(executionEntityManager, parentExecution); return; } SubProcess subProcess = execution.getCurrentFlowElement().getSubProcess(); // 如果没有更多活动的子执行,则流程可以继续(例如嵌入式子流程仍有活动元素,我们无法继续) // If there are no more active child executions, the process can be continued // If not (eg an embedded subprocess still has active elements, we cannot continue) if (getNumberOfActiveChildExecutionsForExecution(executionEntityManager, parentExecution.getId()) == 0 || isAllEventScopeExecutions(executionEntityManager, parentExecution)) { ExecutionEntity executionToContinue = null; if (subProcess != null) { // In case of ending a subprocess: go up in the scopes and continue via the parent scope // unless its a compensation, then we don't need to do anything and can just end it // 在结束子流程的情况下:进入范围并通过父范围继续,除非它是补偿,那么我们不需要做任何事情,可以结束它 if (subProcess.isForCompensation()) { Context.getAgenda().planEndExecutionOperation(parentExecution); } else { //处理子流程结束 executionToContinue = handleSubProcessEnd(executionEntityManager, parentExecution, subProcess); } } else { // In the 'regular' case (not being in a subprocess), we use the parent execution to // continue process instance execution // 处理规则执行end executionToContinue = handleRegularExecutionEnd(executionEntityManager, parentExecution); } if (executionToContinue != null) { // only continue with outgoing sequence flows if the execution is // not the process instance root execution (otherwise the process instance is finished) // 如果执行不是流程实例根执行,则仅继续传出序列流(否则流程实例已完成) if (executionToContinue.isProcessInstanceType()) { //流程实例类型 handleProcessInstanceExecution(executionToContinue); } else { Context.getAgenda().planTakeOutgoingSequenceFlowsOperation(executionToContinue, true); } } } }
handleRegularExecution也是做了4件事情
如果执行是父但非流程实例,则必须首先删除所有子执行。
删除执行实例相关数据
多实例子流程中结束执行时:处理多实例子流程,也是处理结束
如果没有更多活动的子执行,则流程可以继续(例如嵌入式子流程仍有活动元素,我们无法继续)
a. 第一中情况在结束子流程的情况下
是补偿:那么我们不需要做任何事情,可以直接结束它
非补偿:处理子流程结束handleSubProcessEnd
b. 非子流程的时候,处理规则执行handleRegularExecutionEnd
上面执行结束后executionToContinue不为空,如果执行不是流程实例根执行,则仅继续传出序列流(否则流程实例已完成)