问题现象:
修改审核人,触发监听,为同一个task生成了重复的跟踪信息
分析:
Activity Workflow修改流程处理人的bug,流程里配置了assignment监听。
修改审核人,业务代码里面需要调用工作流的taskService.setAssignee(String taskId, String userId)方法。
这个方法内部是命令模式,最终执行到TaskEntity.setAssignee(String assignee, boolean dispatchAssignmentEvent, boolean dispatchUpdateEvent)
public void setAssignee(String assignee, boolean dispatchAssignmentEvent, boolean dispatchUpdateEvent) {
CommandContext commandContext = Context.getCommandContext();
if (assignee==null && this.assignee==null) {
// ACT-1923: even if assignee is unmodified and null, this should be stored in history.
if (commandContext!=null) {
commandContext
.getHistoryManager()
.recordTaskAssigneeChange(id, assignee);
}
return;
}
this.assignee = assignee;
// if there is no command context, then it means that the user is calling the
// setAssignee outside a service method. E.g. while creating a new task.
if (commandContext!=null) {
commandContext
.getHistoryManager()
.recordTaskAssigneeChange(id, assignee);
if (assignee != null && processInstanceId != null) {
getProcessInstance().involveUser(assignee, IdentityLinkType.PARTICIPANT);
}
if(!StringUtils.equals(initialAssignee, assignee)) {
fireEvent(TaskListener.EVENTNAME_ASSIGNMENT);
initialAssignee = assignee;
}
if(commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
if(dispatchAssignmentEvent) {
commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_ASSIGNED, this));
}
if(dispatchUpdateEvent) {
commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_UPDATED, this));
}
}
}
}
跟踪源码发现28~31行,会判断分配的人是不是原来的人,如果有变更,不是原来的人,就重新触发assginment事件。
这就是为什么修改审核人会触发流程节点的assingment事件的原因。
总结
既然工作流代码里面这样写了,在assingment事件的实现里面就不能用来创建问题跟踪之类的信息,否则每改一次审核人,都会生成一个新的跟踪信息。
节点创建最适合用的监听事件是create。这样修改的时候,重新assign就不会触发监听。
今天测试了下代码,create事件触发的时候,工作流还没有assign审核人,这样就获取不到和审核人相关的信息(我们是多人会签,多人审核,多审核人存在关联表里)。要去关联表查询审核人的信息,在创建的时候记录日志,可是创建的时候还获取不到审核人信息,这里就自相矛盾了,说明在创建监听里写业务逻辑来记录多人审核这条路不通。
下午想到了,监听事件不变,还是监听assignment,修改审核人的时候,虽然触发assignment然后执行我们自己的记录日志的功能,但是只要判断一下,将未审核的人的日志先删除,然后重新建立日志就行了。
另一种方式是,不使用监听,每个节点手动发起和结束任务,手动记录日志,修改的时候,重新分配审核人就不会走监听。