Search before asking
What happened
通过 public void forceTaskSuccess(User loginUser, long projectCode, Integer taskInstanceId)方法对工作节点实例执行强制成功操作时,如果该节点是工作流中唯一失败/kill 的节点,工作流实例应被自动标记为
SUCCESS。但实际上工作流实例永远不会被提升为 SUCCESS。
例子:
我现在有两个工作节点实例,一个成功,一个失败

现在我将这个失败的工作节点实例强制成功

按照processService.forceWorkflowInstanceSuccessByTaskInstanceId(task);的逻辑,这里应该是会将对应的工作流实例置为成功。
但是该工作流实例状态并没有更新。
What you expected to happen
这里工作流实例状态成功更新。
How to reproduce
在forceTaskSuccess方法中,任务实例状态先被更新为 FORCED_SUCCESS 并持久化到数据库,然后才调用 processService.forceWorkflowInstanceSuccessByTaskInstanceId(task);
而在 processService.forceWorkflowInstanceSuccessByTaskInstanceId内部,会重新从数据库查询任务实例列表:
List validTaskList = taskInstanceDao.queryValidTaskListByWorkflowInstanceId(workflowInstance.getId());
此时该任务实例在数据库中的状态已经是 FORCED_SUCCESS(同一事务内自己的写操作,应该立马能读到),不再满足 isFailure() || isKill() 的过滤条件:
List 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?
Code of Conduct
Search before asking
What happened
通过 public void forceTaskSuccess(User loginUser, long projectCode, Integer taskInstanceId)方法对工作节点实例执行强制成功操作时,如果该节点是工作流中唯一失败/kill 的节点,工作流实例应被自动标记为
SUCCESS。但实际上工作流实例永远不会被提升为 SUCCESS。
例子:
我现在有两个工作节点实例,一个成功,一个失败
但是该工作流实例状态并没有更新。
What you expected to happen
这里工作流实例状态成功更新。
How to reproduce
在forceTaskSuccess方法中,任务实例状态先被更新为 FORCED_SUCCESS 并持久化到数据库,然后才调用 processService.forceWorkflowInstanceSuccessByTaskInstanceId(task);
而在 processService.forceWorkflowInstanceSuccessByTaskInstanceId内部,会重新从数据库查询任务实例列表:
List validTaskList = taskInstanceDao.queryValidTaskListByWorkflowInstanceId(workflowInstance.getId());
此时该任务实例在数据库中的状态已经是 FORCED_SUCCESS(同一事务内自己的写操作,应该立马能读到),不再满足 isFailure() || isKill() 的过滤条件:
List 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 的情况为:
因此,工作流实例永远无法被标记为 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?
Code of Conduct