SpringBoot Activiti6系列教程(六)-Execution說明

在activiti中有幾個概念常常用,但文檔也沒有講的很清楚,若是不理解,有可能會誤用。本文就詳細探討如下幾個概念java

  • deployment(部署)
  • instance(實例)
  • execution(執行)
  • task(任務)

deployment(部署)

咱們在前面章節講過,bpmn流程模型文件須要經過RepositoryService進行發佈,相同名稱的流程模型從新部署後會升一個版本,但並不影響以前的流程,還未結束的流程仍是會按照發起時候的版本走。所以deployment就表示一次資源的部署,資源類型不必定是bpmn文件,能夠是任意文件。上傳的資源元信息保存在ACT_RE_DEPLOYMENT中,資源內容以二進制形式保存在表ACT_GE_BYTEARRAY中,兩張表經過DEPLOYMENT_ID字段關聯mysql

instance(流程實例)

一個流程每發起一次就是一個實例,實例數也是流程統計的重要數據,一個流程若是有10000個實例就表示這個流程已經被髮起了10000次,流程實例在activiti中是沒有實體表存儲的,在流程發起時系統分配一個實例id(PROC_INST_ID_),在整個流程的流轉中,該實例號都保持不變,所以能夠根據PROC_INST_ID_查詢整個流程運行時的數據。當調用api發起流程時,應用程序應須要把PROC_INST_ID_保存到自身的業務表中,後續對流程的管理和追蹤都須要PROC_INST_ID_,如要查詢指定流程目前審批人信息,執行如下api:sql

TaskService taskService = ProcessEngines.getDefaultProcessEngine().getTaskService();
List<Task> tasks = taskService.createTaskQuery()
        .processInstanceId(instanceId)
        .list();

若是要追蹤流程運行時信息,能夠以PROC_INST_ID_做爲過濾條件,你能夠根據PROC_INST_ID_查詢如下表的信息segmentfault

mysql> SELECT table_name,column_name FROM information_schema.COLUMNS where COLUMN_NAME='PROC_INST_ID_';
+-----------------------+---------------+
| TABLE_NAME            | COLUMN_NAME   |
+-----------------------+---------------+
| ACT_EVT_LOG           | PROC_INST_ID_ |
| ACT_FO_SUBMITTED_FORM | PROC_INST_ID_ |
| ACT_HI_ACTINST        | PROC_INST_ID_ |
| ACT_HI_ATTACHMENT     | PROC_INST_ID_ |
| ACT_HI_COMMENT        | PROC_INST_ID_ |
| ACT_HI_DETAIL         | PROC_INST_ID_ |
| ACT_HI_IDENTITYLINK   | PROC_INST_ID_ |
| ACT_HI_PROCINST       | PROC_INST_ID_ |
| ACT_HI_TASKINST       | PROC_INST_ID_ |
| ACT_HI_VARINST        | PROC_INST_ID_ |
| ACT_RU_EVENT_SUBSCR   | PROC_INST_ID_ |
| ACT_RU_EXECUTION      | PROC_INST_ID_ |
| ACT_RU_IDENTITYLINK   | PROC_INST_ID_ |
| ACT_RU_TASK           | PROC_INST_ID_ |
| ACT_RU_VARIABLE       | PROC_INST_ID_ |
+-----------------------+---------------+
15 rows in set (0.01 sec)

execution(執行)

execution是比較難理解的一個概念,官方的解釋是Represent a 'path of execution' in a process instance,表明流程實例的執行路徑,有點抽象,什麼意思呢,當流程沒有分之,start到end就是一條直線,那麼就只有一條執行路徑,就是一個execution,若是流程有分之,好比平行審批,那麼到平行網關就會分出兩條路徑,這時候就會產生兩個的execution,新的execution經過PARENT_ID_與父exection進行關聯,之因此要這麼設計,我以爲是爲了隔離不一樣執行路徑間數據的隔離,好比在程序分之A上定義了一個變量,程序是不知道流程是否在分之上,在分之B上又從新定義了相同的變量,若是沒有execution的概念就會致使變量被覆蓋。api

有一個比較特別的地方須要注意下,流程實例(ProcessInstance)也是一個execution,實例id(PROC_INST_ID_)就是流程實例在execution表上的id,從源碼上也能夠看出:bash

下面咱們經過兩個具體例子來理解executionoop

  • 簡單無分之流程

以上就是一個簡單的流程,流程發起後到001節點,001審批後到002,002審批後流程結束,經過代碼進行發起,保存實例id,後續經過實例id進行觀察spa

發起代碼設計

public String start() {
    ProcessInstance instance = runtimeService.startProcessInstanceByKey("execution_simple");
    return instance.getId();
}

發起後表信息code

mysql> SELECT id_,PROC_INST_ID_,PARENT_ID_,PROC_DEF_ID_,ROOT_PROC_INST_ID_,ACT_ID_ FROM activiti.ACT_RU_EXECUTION where proc_inst_id_=77508;
+-------+---------------+------------+-------------------+--------------------+---------+
| id_   | PROC_INST_ID_ | PARENT_ID_ | PROC_DEF_ID_      | ROOT_PROC_INST_ID_ | ACT_ID_ |
+-------+---------------+------------+-------------------+--------------------+---------+
| 77508 | 77508         | NULL       | myProcess:2:77507 | 77508              | NULL    |
| 77509 | 77508         | 77508      | myProcess:2:77507 | 77508              | task1   |
+-------+---------------+------------+-------------------+--------------------+---------+
2 rows in set (0.01 sec)

mysql> select ID_,EXECUTION_ID_,PROC_INST_ID_,PROC_DEF_ID_,NAME_,TASK_DEF_KEY_ from ACT_RU_TASK WHERE PROC_INST_ID_=77508;
+-------+---------------+---------------+-------------------+-------+---------------+
| ID_   | EXECUTION_ID_ | PROC_INST_ID_ | PROC_DEF_ID_      | ASSIGNEE_ | TASK_DEF_KEY_ |
+-------+---------------+---------------+-------------------+-----------+---------------+
| 77512 | 77509         | 77508         | myProcess:2:77507 | 001       | task1         |
+-------+---------------+---------------+-------------------+-----------+---------------+
1 row in set (0.00 sec)

咱們能夠獲得如下幾個信息

  • PROC_INST_ID_爲77508,和第一條exection的id同樣
  • 目前有產生兩個execution,77512的task對應的execution爲77509
  • 77509的父execution是77508也就是流程實例的execution,ACT_ID_爲task1,也就是第一個節點,說明目前該execution目前停留在第一個節點

001審批後表信息

mysql> SELECT id_,PROC_INST_ID_,PARENT_ID_,PROC_DEF_ID_,ROOT_PROC_INST_ID_,ACT_ID_ FROM activiti.ACT_RU_EXECUTION where proc_inst_id_=77508;
+-------+---------------+------------+-------------------+--------------------+---------+
| id_   | PROC_INST_ID_ | PARENT_ID_ | PROC_DEF_ID_      | ROOT_PROC_INST_ID_ | ACT_ID_ |
+-------+---------------+------------+-------------------+--------------------+---------+
| 77508 | 77508         | NULL       | myProcess:2:77507 | 77508              | NULL    |
| 77509 | 77508         | 77508      | myProcess:2:77507 | 77508              | task2   |
+-------+---------------+------------+-------------------+--------------------+---------+
2 rows in set (0.00 sec)

mysql> select ID_,EXECUTION_ID_,PROC_INST_ID_,PROC_DEF_ID_,ASSIGNEE_,TASK_DEF_KEY_ from ACT_RU_TASK WHERE PROC_INST_ID_=77508;
+-------+---------------+---------------+-------------------+-------+---------------+
| ID_   | EXECUTION_ID_ | PROC_INST_ID_ | PROC_DEF_ID_      | ASSIGNEE_ | TASK_DEF_KEY_ |
+-------+---------------+---------------+-------------------+-----------+---------------+
| 77515 | 77509         | 77508         | myProcess:2:77507 | 002       | task2         |
+-------+---------------+---------------+-------------------+-------------+---------------+
1 row in set (0.00 sec)

execution信息不變,由於當前流程沒有分之。

  • 平行審批流程

流程發起

mysql> SELECT id_,PROC_INST_ID_,PARENT_ID_,PROC_DEF_ID_,ROOT_PROC_INST_ID_,ACT_ID_ FROM activiti.ACT_RU_EXECUTION where proc_inst_id_=80011;
+-------+---------------+------------+-------------------------+--------------------+---------+
| id_   | PROC_INST_ID_ | PARENT_ID_ | PROC_DEF_ID_            | ROOT_PROC_INST_ID_ | ACT_ID_ |
+-------+---------------+------------+-------------------------+--------------------+---------+
| 80011 | 80011         | NULL       | parallelProcess:1:80009 | 80011              | NULL    |
| 80012 | 80011         | 80011      | parallelProcess:1:80009 | 80011              | task1   |
+-------+---------------+------------+-------------------------+--------------------+---------+
2 rows in set (0.00 sec)

mysql> mysql> select ID_,EXECUTION_ID_,PROC_INST_ID_,PROC_DEF_ID_,ASSIGNEE_,TASK_DEF_KEY_ from ACT_RU_TASK WHERE PROC_INST_ID_=80011;
+-------+---------------+---------------+-------------------------+-----------+---------------+
| ID_   | EXECUTION_ID_ | PROC_INST_ID_ | PROC_DEF_ID_            | ASSIGNEE_ | TASK_DEF_KEY_ |
+-------+---------------+---------------+-------------------------+-----------+---------------+
| 80015 | 80012         | 80011         | parallelProcess:1:80009 | 001       | task1         |
+-------+---------------+---------------+-------------------------+-----------+---------------+
1 row in set (0.00 sec)

001審批後

mysql> SELECT id_,PROC_INST_ID_,PARENT_ID_,PROC_DEF_ID_,ROOT_PROC_INST_ID_,ACT_ID_ FROM activiti.ACT_RU_EXECUTION where proc_inst_idINST_ID_=80011;
+-------+---------------+------------+-------------------------+--------------------+---------+
| id_   | PROC_INST_ID_ | PARENT_ID_ | PROC_DEF_ID_            | ROOT_PROC_INST_ID_ | ACT_ID_ |
+-------+---------------+------------+-------------------------+--------------------+---------+
| 80011 | 80011         | NULL       | parallelProcess:1:80009 | 80011              | NULL    |
| 80012 | 80011         | 80011      | parallelProcess:1:80009 | 80011              | task3   |
| 80018 | 80011         | 80011      | parallelProcess:1:80009 | 80011              | task2   |
+-------+---------------+------------+-------------------------+--------------------+---------+
3 rows in set (0.00 sec)

mysql> select ID_,EXECUTION_ID_,PROC_INST_ID_,PROC_DEF_ID_,ASSIGNEE_,TASK_DEF_KEY_ from ACT_RU_TASK WHERE PROC_INST_ID_=80011;
+-------+---------------+---------------+-------------------------+-----------+---------------+
| ID_   | EXECUTION_ID_ | PROC_INST_ID_ | PROC_DEF_ID_            | ASSIGNEE_ | TASK_DEF_KEY_ |
+-------+---------------+---------------+-------------------------+-----------+---------------+
| 80020 | 80012         | 80011         | parallelProcess:1:80009 | 003       | task3         |
| 80023 | 80018         | 80011         | parallelProcess:1:80009 | 002       | task2         |
+-------+---------------+---------------+-------------------------+-----------+---------------+
2 rows in set (0.00 sec)

能夠看出80018是新建立的execution,task3複用了原來的exection 80012,兩個execution的父id都是80011,也就是流程實例execution。

003審批後

mysql> SELECT id_,PROC_INST_ID_,PARENT_ID_,PROC_DEF_ID_,ROOT_PROC_INST_ID_,ACT_ID_ FROM activiti.ACT_RU_EXECUTION where proc_inst_id_=80011;
+-------+---------------+------------+-------------------------+--------------------+------------------+
| id_   | PROC_INST_ID_ | PARENT_ID_ | PROC_DEF_ID_            | ROOT_PROC_INST_ID_ | ACT_ID_          |
+-------+---------------+------------+-------------------------+--------------------+------------------+
| 80011 | 80011         | NULL       | parallelProcess:1:80009 | 80011              | NULL             |
| 80012 | 80011         | 80011      | parallelProcess:1:80009 | 80011              | parallelgateway2 |
| 80018 | 80011         | 80011      | parallelProcess:1:80009 | 80011              | task2            |
+-------+---------------+------------+-------------------------+--------------------+------------------+
3 rows in set (0.00 sec)

mysql> select ID_,EXECUTION_ID_,PROC_INST_ID_,PROC_DEF_ID_,ASSIGNEE_,TASK_DEF_KEY_ from ACT_RU_TASK WHERE PROC_INST_ID_=80011;
+-------+---------------+---------------+-------------------------+-----------+---------------+
| ID_   | EXECUTION_ID_ | PROC_INST_ID_ | PROC_DEF_ID_            | ASSIGNEE_ | TASK_DEF_KEY_ |
+-------+---------------+---------------+-------------------------+-----------+---------------+
| 80023 | 80018         | 80011         | parallelProcess:1:80009 | 002       | task2         |
+-------+---------------+---------------+-------------------------+-----------+---------------+
1 row in set (0.00 sec)

80012停留在parallelgateway2上等待80018結束,沒有新的execution產生

002審批後

mysql> SELECT id_,PROC_INST_ID_,PARENT_ID_,PROC_DEF_ID_,ROOT_PROC_INST_ID_,ACT_ID_ FROM activiti.ACT_RU_EXECUTION where proc_inst_id_=80011;
+-------+---------------+------------+-------------------------+--------------------+---------+
| id_   | PROC_INST_ID_ | PARENT_ID_ | PROC_DEF_ID_            | ROOT_PROC_INST_ID_ | ACT_ID_ |
+-------+---------------+------------+-------------------------+--------------------+---------+
| 80011 | 80011         | NULL       | parallelProcess:1:80009 | 80011              | NULL    |
| 80018 | 80011         | 80011      | parallelProcess:1:80009 | 80011              | task4   |
+-------+---------------+------------+-------------------------+--------------------+---------+
2 rows in set (0.00 sec)

mysql> select ID_,EXECUTION_ID_,PROC_INST_ID_,PROC_DEF_ID_,ASSIGNEE_,TASK_DEF_KEY_ from ACT_RU_TASK WHERE PROC_INST_ID_=80011;
+-------+---------------+---------------+-------------------------+-----------+---------------+
| ID_   | EXECUTION_ID_ | PROC_INST_ID_ | PROC_DEF_ID_            | ASSIGNEE_ | TASK_DEF_KEY_ |
+-------+---------------+---------------+-------------------------+-----------+---------------+
| 80028 | 80018         | 80011         | parallelProcess:1:80009 | 004       | task4         |
+-------+---------------+---------------+-------------------------+-----------+---------------+
1 row in set (0.00 sec)

複用了80018這個execution

004審批後流程結束。

經過以上例子能夠看出

  • 若是沒有分之,就只有兩個execution(另一個是實例execution)
  • 遇到分之節點會產生新的execution,activiti會複用以前的execution,分之合併後保留其中一個execution
實際上不僅是分之,若是一個節點多我的審批,經過 multiInstanceLoopCharacteristics指定,那麼每次循環都會建立一個新的execution,這個就留給讀者自行去驗證。

task(任務)

這裏說的task指的是usertask,usertask就是一我的的待辦,能夠經過activiti提供的api能夠查詢指定人當前待辦信息,當activiti遇到usertask節點就會進入等待狀態,等待用戶審批完成後繼續執行。用戶的待辦任務存儲在ACT_RU_TASK表上。

相關文章
相關標籤/搜索