Springboot +Flowable,任务认领和回退(一)

news/2024/10/31 3:26:02/

一.简介

有的时候,一个任务节点会存在多个候选人,例如:张三提交一个任务,这个任务即可以由李四处理,又可以由王五处理,那么针对这种多个任务候选人的情况,该如何处理?

二.绘制流程图

首先我们还是使用之前旧的流程图,但是在为 UserTask 设置分配用户的时候,我们设置多个用户,流程图截图如下:
在这里插入图片描述

分配图截图如下:
在这里插入图片描述

设置完成后,载这个流程文件,该流程对应的XML文件,内容如下:

<process id="demo01" name="demo01" isExecutable="true"><documentation>demo01</documentation><startEvent id="startEvent1" flowable:initiator="INITATOR" flowable:formFieldValidation="true"></startEvent><userTask id="sid-5F901234-AFF1-480E-9D66-2D196B910BA3" flowable:candidateUsers="javaboy,zhangsan,lisi" flowable:formFieldValidation="true"></userTask><sequenceFlow id="sid-71FB3A81-F753-419D-9A0A-2FC6E5361CED" sourceRef="startEvent1" targetRef="sid-5F901234-AFF1-480E-9D66-2D196B910BA3"></sequenceFlow><endEvent id="sid-D0B9E5BF-8C1A-4F8F-B2C2-F423F5DC556D"></endEvent><sequenceFlow id="sid-DEBE03CD-F247-4EF3-BB67-ABBA94739B0A" sourceRef="sid-5F901234-AFF1-480E-9D66-2D196B910BA3" targetRef="sid-D0B9E5BF-8C1A-4F8F-B2C2-F423F5DC556D"></sequenceFlow>
</process>

可以看到,UserTask 中的 flowable:candidateUsers=“javaboy,zhangsan,lisi” 就表示这个 UserTask 由 javaboy、zhangsan 和 lisi 三个用户处理,用户名之间用 , 隔开。

三.查询任务处理人

接下来就是部署并启动上面这个流程,具体如何部署如何启动,看之前的文章。
当流程启动成功之后,去查询 javaboy 需要处理的 UserTask,代码如下:

List<Task> list = taskService.createTaskQuery().taskAssignee("javaboy").list();
for (Task task : list) {logger.info("id:{};name:{};taskDefinitionKey:{}", task.getId(), task.getName(), task.getTaskDefinitionKey());
}

发现这个 SQL 执行完成后,查询不到任何数据!这个方法最终查询的是数据库中的 ACT_RU_TASK 表,查询的 SQL 如下:
在这里插入图片描述
去检查 ACT_RU_TASK 表以及它的 ASSIGNEE_ 字段,截图如下:
在这里插入图片描述
发现 ACT_RU_TASK 表中记录的 ASSIGNEE_ 字段值为 null。为 null 这个其实也好理解,因为这个 UserTask 有多个人可以处理,但是只有一个字段,没法储存,肯定有其他存储方式。

这种有多个候选人的任务,应该按照如下方式来查询:

@Test
void test12() {List<Task> list = taskService.createTaskQuery().taskCandidateUser("javaboy").list();for (Task task : list) {logger.info("id:{};name:{};taskDefinitionKey:{}", task.getId(), task.getName(), task.getTaskDefinitionKey());}
}

这里调用 taskCandidateUser 方法进行处理。那么这个方法查询的是哪张表呢?看下上面方法最终执行的 SQL,如下:

: ==>  Preparing: SELECT RES.* from ACT_RU_TASK RES WHERE RES.ASSIGNEE_ is null and exists(select LINK.ID_ from ACT_RU_IDENTITYLINK LINK where LINK.TYPE_ = 'candidate' and LINK.TASK_ID_ = RES.ID_ and ( LINK.USER_ID_ = ? ) ) order by RES.ID_ asc
: ==> Parameters: javaboy(String)
: <==      Total: 1

这里的查询涉及到两张表,分别是 ACT_RU_TASKACT_RU_IDENTITYLINK,两张表联合查询查出来的,来看看 ACT_RU_IDENTITYLINK 表的内容,截图如下:
在这里插入图片描述
TYPE_ 为 candidate 的就表示这个 Task 的候选人,id 为 c5693038-3f42-11ed-b9e2-acde48001122 的 Task 一共有三个候选人,两张表联合查询,才可以查到这个 UserTask 该由谁来处理。

另外一种常见的需求就是,已经知道了要处理的流程实例了,但是不知道应该由谁来处理,此时通过查询 ACT_RU_IDENTITYLINK 表就可以确定一个流程实例都有哪些参与者,代码如下:

@Test
void test13() {List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().list();for (ProcessInstance pi : list) {List<IdentityLink> identityLinksForProcessInstance = runtimeService.getIdentityLinksForProcessInstance(pi.getId());for (IdentityLink identityLink : identityLinksForProcessInstance) {logger.info("ProcessInstanceId:{},UserId:{}",identityLink.getProcessInstanceId(),identityLink.getUserId());}}
}

这个执行的 SQL,截图如下:
在这里插入图片描述
可以看到,其实就是通过查询 ACT_RU_IDENTITYLINK 表获取的数据。


http://www.ppmy.cn/news/60337.html

相关文章

知识图谱学习笔记01-引言

起源 知识图谱的概念最早可以追溯到20世纪60年代的人工智能领域&#xff0c;但其真正的起源可以追溯到20世纪90年代初的万维网时代。 在这个时期&#xff0c;互联网的爆炸性增长和数据的迅速积累使得人们意识到需要更好地组织和利用这些数据。因此&#xff0c;人们开始研究如…

MYSQL-数据库管理(下)

查看数据库信息 show database 查看数据库中的表信息 use 数据库名 #切换到书库中 show tables show tables in mysql 显示数据表的结构&#xff08;字段&#xff09; describe user; Field:字段名称 type:数据类型 Null :是否允许为空 Key :主键 Type:数据类型 Null :是否…

如何在Firefox中使用最小字体

关于firefox最小字体的设置 firefox最小字体的设置方法 首先打开firefox浏览器&#xff0c;然后点击菜单栏上的“查看”按钮&#xff0c;或者使用快捷键“Ctrl0”。 在弹出的菜单栏中选择“缩放”选项&#xff0c;然后选择“较小字体”。 这时&#xff0c;浏览器的字体将变得更…

如何在 Windows 11 启用 Hyper-V

准备在本机玩一下k8s&#xff0c;需要先启用 Hyper-V&#xff0c;谁知道这一打开&#xff0c;没有 Hyper-V选项&#xff1a; 1、查看功能截图&#xff1a; 2、以下文件保存记事本&#xff0c;然后重命名为*.bat pushd "%~dp0" dir /b %SystemRoot%\servicing\Packa…

关于I帧/IDR、B帧、P帧、SPS、PPS

在h264编解码中&#xff0c;常常有I帧/IDR/B帧/P帧/IDR/NALU/GOP/&#xff0c;但往往没有关注细节。或者我们本身在实际应用中已使用过很多次&#xff0c;但对相关的技术名词不清楚。 在H264协议里定义了三种帧&#xff0c;完整编码的帧叫I帧&#xff0c;参考之前的I帧生成的只…

JVM学习随笔02——虚拟机内存区组成与内存溢出异常

一、Java虚拟机内存区组成图 1、程序计数器&#xff1a; 每个线程独占一个计数器&#xff0c;用来指示该线程下一条要执行的指令的地址。这一部分不会导致内存异常。PS&#xff1a;如果一个线程进入的是一般的Java方法&#xff0c;计数器指示的是下一条指令地址&#xff1b;如果…

知识变现海哥|知识付费 VS 知识免费

知识付费 VS 知识免费 1 大家好&#xff0c;我是海哥&#xff0c;知识变现创业教练&#xff0c;头部教育公司内容总监&#xff0c;海哥知识变现学院创始人&#xff0c;海哥知识变现星球主理人。从事知识变现创业10年&#xff0c;已助力3000人实现知识变现&#xff0c;曾凭一套…

Dubbo源码篇02---从泛化调用探究Wrapper机制的原理

Dubbo源码篇02---从泛化调用探究Wrapper机制的原理 什么是泛化调用从传统三层架构说起反射调用尝试优化 泛化调用泛化调用怎么用通过Spring使用泛化调用 利用泛化调用改造现有服务 泛化调用小结 Wrapper机制自定义代理dubbo底层wrapper原理小结 小结 什么是泛化调用 从传统三层…