技术交流28群

服务热线

135-6963-3175

微信服务号

任务完成命令类源码解析 更新时间 2022-3-20 浏览2582次

我们在完成任务的时候都执行了哪些操作呢?

主要涉及删除表(默认非级联):

ACT_RU_TASK

ACT_RU_IDENTITYLINK

ACT_RU_VARIABLE

主要看一个CompleteTaskCmd:

protected Void execute(CommandContext commandContext, TaskEntity task) {
    // Backwards compatibility
    if (task.getProcessDefinitionId() != null) {
      if (Activiti5Util.isActiviti5ProcessDefinitionId(commandContext, task.getProcessDefinitionId())) {
        Activiti5CompatibilityHandler activiti5CompatibilityHandler = Activiti5Util.getActiviti5CompatibilityHandler(); 
        activiti5CompatibilityHandler.completeTask(task, variables, localScope);
        return null;
      }
    }
    if (variables != null) {
        if (localScope) {
            task.setVariablesLocal(variables);
        } else if (task.getExecutionId() != null) {
            task.setExecutionVariables(variables);
        } else {
            task.setVariables(variables);
        }
    }
    
    if (transientVariables != null) {
      if (localScope) {
        task.setTransientVariablesLocal(transientVariables);
      } else {
        task.setTransientVariables(transientVariables);
      }
    }
    executeTaskComplete(commandContext, task, variables, localScope);
    return null;
}

看上面代码主要进行了:1、变量的绑定(更新变量缓存或入库ACT_HI_VARINST历史变量实例表)

                                 2、执行完成任务executeTaskComplete
继续看方法:

protected void executeTaskComplete(CommandContext commandContext, TaskEntity taskEntity, Map<String, Object> variables, boolean localScope) {
    // Task complete logic
    if (taskEntity.getDelegationState() != null && taskEntity.getDelegationState().equals(DelegationState.PENDING)) {
      throw new ActivitiException("A delegated task cannot be completed, but should be resolved instead.");
    }
    //1.触发complete监听器
    commandContext.getProcessEngineConfiguration().getListenerNotificationHelper().executeTaskListeners(taskEntity, TaskListener.EVENTNAME_COMPLETE);
    if (Authentication.getAuthenticatedUserId() != null && taskEntity.getProcessInstanceId() != null) {
      ExecutionEntity processInstanceEntity = commandContext.getExecutionEntityManager().findById(taskEntity.getProcessInstanceId());
      //设置为参与者入库ACT_RU_IDENTITYLINK表(若该用户未与流程实例关联)
      commandContext.getIdentityLinkEntityManager().involveUser(processInstanceEntity, Authentication.getAuthenticatedUserId(),IdentityLinkType.PARTICIPANT);
    }
    //2.分发器触发"任务完成"事件
    ActivitiEventDispatcher eventDispatcher = Context.getProcessEngineConfiguration().getEventDispatcher();
    if (eventDispatcher.isEnabled()) {
      if (variables != null) {
        eventDispatcher.dispatchEvent(ActivitiEventBuilder.createEntityWithVariablesEvent(ActivitiEventType.TASK_COMPLETED, taskEntity, variables, localScope));
      } else {
        eventDispatcher.dispatchEvent(ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_COMPLETED, taskEntity));
      }
    }
    //3.删除任务
    //删除该task下的子任务、人员、变量;更新历史任务的完成事件耗时等
    commandContext.getTaskEntityManager().deleteTask(taskEntity, null, false, false);
    // Continue process (if not a standalone task)
    if (taskEntity.getExecutionId() != null) {
      ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findById(taskEntity.getExecutionId());
      //4.触发执行实例
      Context.getAgenda().planTriggerExecutionOperation(executionEntity);
    }
  }

分析,主要进行了如下操作:

1、触发complete任务监听器

2、当前人不为null,设置为参与者入库ACT_RU_IDENTITYLINK表(若该用户未与流程实例关联)

3、分发器触发活动"任务完成"事件

4、删除任务
    //删除该task下的子任务、人员、变量;更新历史任务的完成事件耗时等

5、触发执行实例继续执行


我们主要分析步骤4

commandContext.getTaskEntityManager().deleteTask(taskEntity, null, false, false);

看deleteTask源码:

@Override
  public void deleteTask(TaskEntity task, String deleteReason, boolean cascade, boolean cancel) {
    if (!task.isDeleted()) {//未被删除则执行
      //1、触发task上delete事件类型的监听器
      getProcessEngineConfiguration().getListenerNotificationHelper()
        .executeTaskListeners(task, TaskListener.EVENTNAME_DELETE);
      task.setDeleted(true);
      String taskId = task.getId();
     //2、去ACT_RU_TASK查子任务
      List<Task> subTasks = findTasksByParentTaskId(taskId);
      for (Task subTask : subTasks) {//递归删除
        deleteTask((TaskEntity) subTask, deleteReason, cascade, cancel);
      }
      //3、去ACT_RU_IDENTITYLINK查该task下的所有人员进行遍历删除
      getIdentityLinkEntityManager().deleteIdentityLinksByTaskId(taskId);
      //4、删除该task下所有ACT_RU_VARIABLE变量数据
      getVariableInstanceEntityManager().deleteVariableInstanceByTask(task);
      if (cascade) {//级联
        /*
        查询子历史任务实例、递归删除:
          1、当最高审计级别,删除ACT_HI_DETAIL表记录
          2、当>=activity级别,删除历史变量ACT_HI_VARINST表记录
          3、非none级别,删除ACT_HI_COMMENT历史批注表记录
          4、非none,删除ACT_HI_ATTACHMENT表记录,若附件的contentId不为null,则删除ACT_GE_BYTEARRAY表记录附件(通过附件内容id)
          5、查ACT_HI_IDENTITYLINK,遍历删除
          6、删除ACT_HI_TASKINST表记录
        * */
        getHistoricTaskInstanceEntityManager().delete(taskId);
      } else {
        //查询ACT_HI_TASKINST 历史task实例设置删除原因、结束事件、耗时
        getHistoryManager().recordTaskEnd(taskId, deleteReason);
      }
      //删除ACT_RU_TASK表记录
      delete(task, false);
      if (getEventDispatcher().isEnabled()) {
           //当要取消任务时,创建并触发userTask任务取消事件
      if (cancel && task.isCanceled() == false) {
      task.setCanceled(true);
          getEventDispatcher().dispatchEvent(
                  ActivitiEventBuilder.createActivityCancelledEvent(task.getExecution() != null ? task.getExecution().getActivityId() : null, 
                      task.getName(), task.getExecutionId(), 
                      task.getProcessInstanceId(),
                      task.getProcessDefinitionId(), 
                      "userTask", 
                      deleteReason));
        }
        
        getEventDispatcher().dispatchEvent(ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_DELETED, task));
      }
    }
}

分析上面代码,执行了如下操作:

前提:task状态未被删除则执行:

1、触发task上delete事件类型的监听器

2、去ACT_RU_TASK查子任务递归删除

    2.1、去ACT_RU_IDENTITYLINK查该task下的所有人员进行遍历删除

    2.2、删除该task下所有ACT_RU_VARIABLE变量数据

    2.3、级联:

                查询子历史任务实例、递归删除:

                  1、当最高审计级别,删除ACT_HI_DETAIL表记录

                  2、当>=activity级别,删除历史变量ACT_HI_VARINST表记录

                  3、非none级别,删除ACT_HI_COMMENT历史批注表记录

                  4、非none,删除ACT_HI_ATTACHMENT表记录,若附件的contentId不为null,则删除ACT_GE_BYTEARRAY表记录附件(通过附件内容id)

                  5、查ACT_HI_IDENTITYLINK,遍历删除

                  6、删除ACT_HI_TASKINST表记录

             否则:

                 查询ACT_HI_TASKINST 历史task实例设置删除原因、结束事件、耗时

     2.4 删除ACT_RU_TASK表记录

     2.5 当要取消任务时,则task.setCanceled(true);

           创建并触发userTask任务取消事件。