掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
今天來和小伙伴們聊一聊流程的掛起和激活。

長樂網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,長樂網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為長樂上1000+提供企業(yè)網(wǎng)站建設(shè)服務。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站制作要多少錢,請找那個售后服務好的長樂做網(wǎng)站的公司定做!
這塊實際上涉及到兩部分內(nèi)容:
流程定義的掛起和激活。
流程實例的掛起和激活。
一個定義好的流程,如果掛起了,那么就無法據(jù)此創(chuàng)建新的流程。
一個流程實例如果掛起了,那么就無法執(zhí)行流程中的任務。
小伙伴們注意區(qū)分這兩個概念(看了前面幾篇文章的小伙伴,應該對于這兩個概念不在話下了)。
我們分別來看。
對于一個定義好的流程,我們可以通過如下方法來查看這個流程是否掛起:
@Test
void test05() {
Listlist = repositoryService.createProcessDefinitionQuery().list();
for (ProcessDefinition processDefinition : list) {
String id = processDefinition.getId();
boolean suspended = repositoryService.isProcessDefinitionSuspended(id);
if (suspended) {
logger.info("流程定義 {} 已掛起",processDefinition.getName());
}else{
logger.info("流程定義 {} 未掛起",processDefinition.getName());
}
}
}
這個查詢 SQL 涉及到的表是 ACT_RE_PROCDEF,該表中有一個名為 SUSPENSION_STATE_ 的字段,該字段表示這個流程是否掛起。如下圖:
1 表示流程沒有掛起。
執(zhí)行如下方法,可以掛起一個流程定義,如下:
@Test
void test06() {
Listlist = repositoryService.createProcessDefinitionQuery().list();
for (ProcessDefinition pd : list) {
repositoryService.suspendProcessDefinitionById(pd.getId());
}
}
掛起的原理其實很簡單,就是去 ACT_RE_PROCDEF 表中,將 SUSPENSION_STATE_ 字段的值設(shè)置為 2,就表示這個流程定義掛起了,我們可以看下流程定義掛起時執(zhí)行的 SQL:
從這個執(zhí)行的 SQL 中我們可以清晰的看到,操作的表是 ACT_RE_PROCDEF,修改的字段就是 SUSPENSION_STATE_,將該字段的值修改為 2(樂觀鎖相關(guān)的 REV_ 字段不考慮)。
對于一個已經(jīng)掛起的流程定義,如果我們想據(jù)此啟動一個流程,如下:
@Test
void test01() {
identityService.setAuthenticatedUserId("wangwu");
ProcessInstance pi = runtimeService.startProcessInstanceByKey("leave");
logger.info("id:{},activityId:{}", pi.getId(), pi.getActivityId());
}
此時就會拋出如下異常:
這個異常說的很明白了,流程定義被掛起了,無法開啟一個新的流程實例。
已經(jīng)掛起的流程定義,還可以激活,方式如下:
@Test
void test07() {
Listlist = repositoryService.createProcessDefinitionQuery().list();
for (ProcessDefinition pd : list) {
repositoryService.activateProcessDefinitionById(pd.getId());
}
}
激活的原理也很簡單,,就是去 ACT_RE_PROCDEF 表中,將 SUSPENSION_STATE_ 字段的值設(shè)置為 1,就表示這個流程定義激活了,我們可以看下流程定義激活時執(zhí)行的 SQL:
大家注意看操作的表、字段以及對應的參數(shù)。
第一小節(jié)搞懂了,第二小節(jié)就容易多了。
掛起一個流程實例的方式如下:
@Test
void test08() {
Listlist = repositoryService.createProcessDefinitionQuery().list();
for (ProcessDefinition pd : list) {
repositoryService.suspendProcessDefinitionById(pd.getId(), true, null);
}
}
小伙伴們看到,其實還是剛才上面的那個方法,只不過這里多了兩個參數(shù):
第二個參數(shù) true 表示是否要掛起這個流程定義對應的所有的流程實例,true 表示掛起。
第三個參數(shù) null 表示流程掛起的具體時間,如果該參數(shù)為 null,則流程會被立馬掛起,如果該參數(shù)是一個具體的日期,則到期之后流程才會被掛起,但是這個需要 job executor 的支持,關(guān)于 job executor,松哥后面再單獨發(fā)文章和小伙伴們介紹。
執(zhí)行完成之后,這個流程實例就被掛起了。流程實例被掛起,涉及到兩個地方:
流程的執(zhí)行實例被掛起。
流程的 Task 被掛起。
也就是首先 ACT_RU_EXECUTION 表中對應的流程實例會被掛起:
最后一列兩個 2 就說明這兩個執(zhí)行實例被掛起了。
同時,流程實例的 Task 其實也被掛起了,即 ACT_RU_TASK 表中與之對應的任務被掛起了,如下:
可以看到,SUSPENSION_STATE_ 字段的值為 2,表示這 Task 也被掛起了。
我們來看看掛起流程實例時執(zhí)行的 SQL:
注意,流程定義本身也被掛起了。
對于處于掛起狀態(tài)的流程實例,是無法繼續(xù)執(zhí)行的,如果強行執(zhí)行,如下:
@Test
void test03() {
Listlist = taskService.createTaskQuery().taskAssignee("wangwu").list();
for (Task task : list) {
taskService.complete(task.getId());
}
}
則會拋出異常,如下:
這個異常也說的很清楚了,無法完成一個處于掛起狀態(tài)的 Task。
處于掛起狀態(tài)的流程實例,可以通過如下方式激活:
@Test
void test09() {
Listlist = repositoryService.createProcessDefinitionQuery().list();
for (ProcessDefinition pd : list) {
repositoryService.activateProcessDefinitionById(pd.getId(), true, null);
}
}
一共三個參數(shù):
激活就是反向操作,將 ACT_RU_EXECUTION、ACT_RU_TASK 以及 ACT_RE_PROCDEF 表中的 SUSPENSION_STATE_ 字段值再改為 1。對應的 SQL 如下:

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流