Skip to content

[Bug] [api] When forceTaskSuccess is performed on the last unsuccessful workflow instance, the workflow instance cannot be reset to the Success state. #18247

@fanzhongyu

Description

@fanzhongyu

Search before asking

  • I had searched in the issues and found no similar issues.

What happened

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

例子:
我现在有两个工作节点实例,一个成功,一个失败

Image 现在我将这个失败的工作节点实例强制成功 Image 按照processService.forceWorkflowInstanceSuccessByTaskInstanceId(task);的逻辑,这里应该是会将对应的工作流实例置为成功。 Image

但是该工作流实例状态并没有更新。

What you expected to happen

Image

这里工作流实例状态成功更新。

How to reproduce

在forceTaskSuccess方法中,任务实例状态先被更新为 FORCED_SUCCESS 并持久化到数据库,然后才调用 processService.forceWorkflowInstanceSuccessByTaskInstanceId(task);

Image

而在 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?

  • Yes I am willing to submit a PR!

Code of Conduct

Metadata

Metadata

Assignees

Labels

backendbugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions