文章

【若依】30、定时任务

1 流程定义定时激活

在定义一个流程的时候,可以为流程设置一个激活时间,方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
 * 部署工作流(输入流)
 * 定时激活
 * @param file
 * @return
 * @throws IOException
 */
@PostMapping("/deploy4")
public Response deploy4(@RequestPart MultipartFile file) throws IOException {
    DeploymentBuilder deploymentBuilder = repositoryService
            // 开始流程部署的构建
            .createDeployment()
            // ACT_RE_DEPLOYMENT 表中的 NAME_ 属性
            .name("部署工作流的名称")
            // ACT_RE_DEPLOYMENT 表中的 CATEGORY_ 属性
            .category("部署工作流的分类")
            // ACT_RE_DEPLOYMENT 表中的 KEY_ 属性
            .key("部署工作流的 KEY")
            // 设置流程定义的激活时间,在到达这个时间点之前,这个流程定义是不可用的,到达这个时间点之后,就可以通过这个流程定义启动一个流程实例了
            // 流程定义表:ACT_RE_PROCDEF 激活挂起状态字段(2:挂起,1:激活):SUSPENSION_STATE_
            // 定时记录表:ACT_RU_TIMER_JOB
            .activateProcessDefinitionsOn(new Date(System.currentTimeMillis() + 2 * 60 * 1000))
            // 设置文件的输入流,将来通过这个输入流自动去读取 XML 文件
            // 注意:设置资源名称不能随意取值,建议和文件名保持一致
            .addInputStream(file.getOriginalFilename(), file.getInputStream());
    // 完成部署
    Deployment deployment = deploymentBuilder.deploy();
    return Response.success("部署成功", deployment.getId());
}

带有激活时间的流程定义,在刚定义好的时候,ACT_RE_PROCDEF表中的SUSPENSION_STATE_字段的值为 2,表示这个流程定义处于挂起状态,无法使用。 此时,在ACT_RU_TIMER_JOB表中,保存了将要执行的定时任务,该表中有一个DUEDATE_字段,该字段保存了这个定时任务执行的具体时间,到这个时间点之后,定时任务会自动执行,会自动将ACT_RE_PROCDEF表中的SUSPENSION_STATE_字段更新为 1,表示这个流程定义是可用的了,此时就可以通过这个流程定义去启动一个流程实例了。

2 流程实例定时挂起与定时激活

定时挂起

1
2
3
4
5
6
@Test
void suspendProcessDefinitionByKey() {
    // 定时挂起流程定义包括所对应的流程实例
    // 3分钟后,会挂起 HistoryDemo01 流程定义以及所对应的流程实例
    repositoryService.suspendProcessDefinitionByKey("HistoryDemo01", true, new Date(System.currentTimeMillis() + 3 * 60 * 1000));
}

定时激活

1
2
3
4
5
@Test
void activateProcessDefinitionByKey() {
    // 定时激活
    repositoryService.activateProcessDefinitionByKey("HistoryDemo01", true, new Date(System.currentTimeMillis() + 3 * 60 * 1000));
}

3 定时任务执行过程分析

根据前面的介绍,定时任务信息会保存在ACT_RU_TIMER_JOB表中,时间到了就会自动执行。 实际上,每次需要执行哪一个定时任务,并不是去ACT_RU_TIMER_JOB表中查找这个定时任务的;而是,每次都会去ACT_RU_JOB表中查找数据,如果在ACT_RU_JOB表中,查找到数据,就会立马执行。 在 Flowable 中,当定时任务的时间到了之后,数据会自动从ACT_RU_TIMER_JOB表中移动到ACT_RU_JOB表中,然后当定时器查询到ACT_RU_JOB表中的数据之后,就立马执行了。 栗子:在3分钟之后,挂起一个流程定义和流程实例:

1
2
3
4
5
6
@Test
void suspendProcessDefinitionByKey() {
    // 定时挂起流程定义包括所对应的流程实例
    // 3分钟后,会挂起 HistoryDemo01 流程定义以及所对应的流程实例
    repositoryService.suspendProcessDefinitionByKey("HistoryDemo01", true, new Date(System.currentTimeMillis() + 3 * 60 * 1000));
}

当这行代码执行完,在3分钟之后,这个流程定义以及所对应的流程实例,统统都会挂起。 1、如果时间还没到,但是不想挂起了:

1
2
3
4
5
@Test
void moveJobToDeadLetterJob() {
    // 将 ACT_RU_TIMER_JOB 表中的定时任务移动到 ACT_RU_DEADLETTER_JOB 表中,此时这个定时任务将不会再执行
    managementService.moveJobToDeadLetterJob("579d726c-5dc5-11ed-a105-acde48001122");
}

对于已经移动到死信队列中的任务,也可以再次移动回ACT_RU_JOB表中,移动回ACT_RU_JOB表中之后,这个定时任务就会被立马执行,无论时间到没到。

1
2
3
4
5
@Test
void moveDeadLetterJobToExecutableJob() {
    // 将死信队列中的记录移动到 ACT_RU_JOB 表中,移动成功之后,这个定时任务就会立马被执行
    managementService.moveDeadLetterJobToExecutableJob("579d726c-5dc5-11ed-a105-acde48001122", 3);
}

2、如果不想在3分钟之后执行,而是想立马将之挂起:

1
2
3
4
5
@Test
void moveTimerToExecutableJob() {
    // 将 ACT_RU_TIMER_JOB 表中的定时任务移动到 ACT_RU_JOB 中,ACT_RU_JOB 表中的任务被扫描到之后,就会立马执行
    managementService.moveTimerToExecutableJob("14309833-5dc6-11ed-b1d6-acde48001122");
}
本文由作者按照 CC BY 4.0 进行授权