fanzhongyu opened a new issue, #18247:
URL: https://github.com/apache/dolphinscheduler/issues/18247

   ### Search before asking
   
   - [x] I had searched in the 
[issues](https://github.com/apache/dolphinscheduler/issues?q=is%3Aissue) and 
found no similar issues.
   
   
   ### What happened
   
   通过 public void forceTaskSuccess(User loginUser, long projectCode, Integer 
taskInstanceId)方法对工作节点实例执行强制成功操作时,如果该节点是工作流中唯一失败/kill 的节点,工作流实例应被自动标记为
     SUCCESS。但实际上工作流实例永远不会被提升为 SUCCESS。
   
   **例子:**
   我现在有两个工作节点实例,一个成功,一个失败
   
   <img width="907" height="428" alt="Image" 
src="https://github.com/user-attachments/assets/850952f3-553d-4962-9f25-0681ecb0fa68";
 />
   现在我将这个失败的工作节点实例强制成功
   
   <img width="1587" height="284" alt="Image" 
src="https://github.com/user-attachments/assets/cc1884d7-248c-4ed5-b2c9-1501a322a928";
 />
   
按照processService.forceWorkflowInstanceSuccessByTaskInstanceId(task);的逻辑,这里应该是会将对应的工作流实例置为成功。
   
   <img width="1266" height="280" alt="Image" 
src="https://github.com/user-attachments/assets/d10f552f-62c6-40d2-a668-2a241db52ece";
 />
   
   但是该工作流实例状态并没有更新。
   
   
   ### What you expected to happen
   
   <img width="1266" height="280" alt="Image" 
src="https://github.com/user-attachments/assets/8fb69d49-a3f5-443c-a7ed-cf1f2be2e428";
 />
   
   这里工作流实例状态成功更新。
   
   ### How to reproduce
   
   在forceTaskSuccess方法中,任务实例状态先被更新为 FORCED_SUCCESS 并持久化到数据库,然后才调用 
processService.forceWorkflowInstanceSuccessByTaskInstanceId(task);
   
   <img width="1117" height="540" alt="Image" 
src="https://github.com/user-attachments/assets/9174052b-8ee3-494f-8053-6710a210792d";
 />
   
   
   而在 
processService.forceWorkflowInstanceSuccessByTaskInstanceId内部,会重新从数据库查询任务实例列表:
   List<TaskInstance> validTaskList = 
taskInstanceDao.queryValidTaskListByWorkflowInstanceId(workflowInstance.getId());
   
   此时该任务实例在数据库中的状态已经是 FORCED_SUCCESS(同一事务内自己的写操作,应该立马能读到),不再满足 isFailure() || 
isKill() 的过滤条件:
   
   List<Integer> failTaskList = validTaskList.stream()
         .filter(instance -> instance.getState().isFailure() || 
instance.getState().isKill())
         .map(TaskInstance::getId).collect(Collectors.toList());
   if (failTaskList.size() == 1 && failTaskList.contains(task.getId())) {
         // 永远无法进入 — failTaskList 中不包含已被强制成功的任务
   }
   
    由于被强制成功的任务不再是 failure/kill 状态,failTaskList 的情况为:
     - 如果它是唯一的失败节点 → failTaskList 为空 → 条件不满足
     - 如果还有其他失败节点 → failTaskList 中不包含当前 task → 
failTaskList.contains(task.getId()) 返回 false
   
   因此,工作流实例永远无法被标记为 SUCCESS。
   
   **修复方案:**
   调换调用顺序:在更新任务实例状态之前先调用 
forceWorkflowInstanceSuccessByTaskInstanceId(),使其内部查询时能读到原始的 failure/kill 状态:
   processService.forceWorkflowInstanceSuccessByTaskInstanceId(task);
   // change the state of the task instance
   task.setState(TaskExecutionStatus.FORCED_SUCCESS);
   task.setEndTime(new Date());
   int changedNum = taskInstanceMapper.updateById(task);
   if (changedNum <= 0) {
       throw new ServiceException(Status.FORCE_TASK_SUCCESS_ERROR);
   }
   
   ### Anything else
   
   _No response_
   
   ### Version
   
   dev
   
   ### Are you willing to submit PR?
   
   - [ ] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [x] I agree to follow this project's [Code of 
Conduct](https://www.apache.org/foundation/policies/conduct)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: 
[email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to