flowable 上一節(jié)點任務(wù)撤回-(6)調(diào)用式子流程

場景:本章主要描述 下一節(jié)點為調(diào)用子流程 如何進行回退操作。

調(diào)用式子流程

上一章:flowable 上一節(jié)點任務(wù)撤回-(5)嵌入式子流程

環(huán)境
springboot:2.2.0.RELEASE
flowable:6.4.2

git地址:https://github.com/oldguys/flowable-modeler-demo/tree/branch_with_flowable_examples

所有章節(jié):

  1. flowable 上一節(jié)點任務(wù)撤回-(1)普通節(jié)點撤回
  2. flowable 上一節(jié)點任務(wù)撤回-(2)會簽任務(wù)(已完成)
  3. flowable 上一節(jié)點任務(wù)撤回-(3)會簽任務(wù)(正在執(zhí)行中)
  4. flowable 上一節(jié)點任務(wù)撤回-(4)多重網(wǎng)關(guān)
  5. flowable 上一節(jié)點任務(wù)撤回-(5)嵌入式子流程
  6. flowable 上一節(jié)點任務(wù)撤回-(6)調(diào)用式子流程

主流程:

調(diào)用式子流程

被調(diào)用流程:

被調(diào)用流程

ACT_RU_EXECUTION
ACT_RU_TASK

調(diào)用式 子流程實質(zhì)流程 2個獨立流程 屿聋,只不過一個流程的 SuperExecution是另一個節(jié)點的 executionId空扎,在子流程完成之后,觸發(fā)主流程的execution完成

NextCallActivityRollbackOperateStrategy:調(diào)用子流程 撤回策略

步驟:

  1. 判斷下一節(jié)點的流程任務(wù)是否已經(jīng)完成润讥,可以利用接口:(原理是:頂級Execution的 ID 實質(zhì)就行 ProcessInstance Id 的特性進行處理)
        callActivityExecutionList = > CommandContextUtil.getExecutionEntityManager(commandContext)
               .findExecutionsByParentExecutionAndActivityIds(hisTask.getProcessInstanceId(), Collections.singletonList(callActivity.getId()));

       // callActivity 在 父級流程的 executionId = 子流程的 processInstanceId
       ExecutionEntity executionEntity = callActivityExecutionList.get(0);

找到子流程的流程實例之后勺卢,對獲取已完成任務(wù)列表就輕松多了。然后采取之前的邏輯象对,如果未進行任務(wù)操作黑忱,則可以進行回退的前置條件。

  1. 創(chuàng)建任務(wù) execution勒魔,與普通節(jié)點一致甫煞,注意像SubProcess從相鄰節(jié)點獲取Execution,畢竟原來任務(wù)executio已經(jīng)消失冠绢。
  2. 刪除正在執(zhí)行任務(wù)抚吠,注意需要把 頂級節(jié)點 Execution和 主流程的 execution刪除。
  3. 處理相關(guān)數(shù)據(jù)
基于模板方法模式弟胀,構(gòu)建編寫通用 RollbackOperateStrategy.process() 操作
    @Override
    public void process(CommandContext commandContext, String assignee, Map<String, Object> variables) {

        this.commandContext = commandContext;
        this.assignee = assignee;
        this.variables = variables;

        log.info("處理 existNextFinishedTask");
        existNextFinishedTask();
        log.info("配置任務(wù)執(zhí)行人 setAssignee");
        setAssignee();
        log.info("處理 createExecution");
        createExecution();
        log.info("處理 deleteRuntimeTasks");
        deleteRuntimeTasks();
        log.info("處理 deleteHisActInstance");
        deleteHisActInstance();
    }
判斷已完成任務(wù)策略 existNextFinishedTask()
 @Override
    public void existNextFinishedTask() {

        HistoricTaskInstance hisTask = paramsTemplate.getHisTask();

        Map<String, CallActivity> callActivityMap = paramsTemplate.getCallActivityMap();
        String key = callActivityMap.keySet().iterator().next();
        this.callActivity = callActivityMap.get(key);

        // 下一節(jié)點callActivity的 flowId
        callActivityExecutionList = CommandContextUtil.getExecutionEntityManager(commandContext)
                .findExecutionsByParentExecutionAndActivityIds(hisTask.getProcessInstanceId(), Collections.singletonList(callActivity.getId()));

        // callActivity 在 父級流程的 executionId = 子流程的 processInstanceId
        ExecutionEntity executionEntity = callActivityExecutionList.get(0);

        // 子流程
        callActivityProcess = CommandContextUtil.getExecutionEntityManager(commandContext)
                .findSubProcessInstanceBySuperExecutionId(executionEntity.getId());

        List<HistoricTaskInstance> hisTaskList = CommandContextUtil.getHistoricTaskService(commandContext)
                .findHistoricTaskInstancesByQueryCriteria(
                        (HistoricTaskInstanceQueryImpl) new HistoricTaskInstanceQueryImpl()
                                .finished()
                                .processInstanceId(callActivityProcess.getId())
                );

        if (!hisTaskList.isEmpty()) {
            throw new FlowableRuntimeException("子流程已經(jīng)具有完成的任務(wù),流程無法回退");
        }
    }
createExecution()

    @Override
    public void createExecution() {
        HistoricTaskInstance hisTask = paramsTemplate.getHisTask();
        ExecutionEntity executionEntity = CommandContextUtil.getExecutionEntityManager(commandContext)
                .findById(hisTask.getExecutionId());

        if (null == executionEntity) {
            log.info("沒有找到execution");
            executionEntity = callActivityExecutionList.get(0);
        }

        ExecutionEntity newExecution = CommandContextUtil.getExecutionEntityManager(commandContext)
                .createChildExecution(executionEntity.getParent());

        // 創(chuàng)建新任務(wù)
        createExecution(newExecution);
        // 移除歷史任務(wù)
        removeHisTask(hisTask);
    }

清除已經(jīng)生成任務(wù)

    @Override
    public void deleteRuntimeTasks() {

        ExecutionEntity parentExecution = callActivityExecutionList.get(0);


        // 清理子流程
        cleanCallActivityProcessInstance(callActivityProcess);
        // 清理主流程記錄
        CommandContextUtil.getExecutionEntityManager(commandContext)
                .delete(parentExecution);

    }

    /**
     * // 無效操作
     * CommandContextUtil.getExecutionEntityManager(commandContext)
     * .deleteProcessInstance(callActivityProcess.getId(), "進行流程撤回", false);
     * 清理 調(diào)用子流程 相關(guān)數(shù)據(jù)
     *
     * @param processInstance
     */
    private void cleanCallActivityProcessInstance(ExecutionEntity processInstance) {
        // 移除正在運行任務(wù)信息
        List<Task> list = CommandContextUtil.getTaskService(commandContext)
                .createTaskQuery()
                .processInstanceId(processInstance.getId())
                .list();
        list.forEach(obj->removeRuntimeTaskOperate((TaskEntity) obj));

        // 移除歷史任務(wù)信息
        List<HistoricTaskInstanceEntity> historicTaskInstanceList = CommandContextUtil.getHistoricTaskService(commandContext)
                .findHistoricTasksByProcessInstanceId(processInstance.getId());
        historicTaskInstanceList.forEach(obj->CommandContextUtil.getHistoricTaskService(commandContext).deleteHistoricTask(obj));

        // 移除 子流程實例
        CommandContextUtil.getIdentityLinkService(commandContext).deleteIdentityLinksByProcessInstanceId(processInstance.getId());
        CommandContextUtil.getVariableService(commandContext).deleteVariablesByExecutionId(processInstance.getId());
        CommandContextUtil.getExecutionEntityManager(commandContext).delete(processInstance.getId());
    }

以上 完成對 上一節(jié)點任務(wù)撤回 架構(gòu)設(shè)計 及 第 6 種情況 解決方案講述楷力。
git地址:https://github.com/oldguys/flowable-modeler-demo/tree/branch_with_flowable_examples

總結(jié):
基本上流程撤回的實現(xiàn)思路就是圍繞著:模擬數(shù)據(jù)流喊式,難點在于需要分析比較幾種主要節(jié)點的特性,當節(jié)點特性本質(zhì)熟悉之后萧朝〔砹簦基于這5大類進行組合重寫策略就能解決更加復(fù)雜的場景,見招拆招检柬,以數(shù)據(jù)流本質(zhì)應(yīng)萬變就行献联。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市何址,隨后出現(xiàn)的幾起案子里逆,更是在濱河造成了極大的恐慌,老刑警劉巖用爪,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件原押,死亡現(xiàn)場離奇詭異,居然都是意外死亡偎血,警方通過查閱死者的電腦和手機诸衔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烁巫,“玉大人署隘,你說我怎么就攤上這事⊙窍叮” “怎么了磁餐?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長阿弃。 經(jīng)常有香客問我诊霹,道長,這世上最難降的妖魔是什么渣淳? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任脾还,我火速辦了婚禮,結(jié)果婚禮上入愧,老公的妹妹穿的比我還像新娘鄙漏。我一直安慰自己,他們只是感情好棺蛛,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布怔蚌。 她就那樣靜靜地躺著,像睡著了一般旁赊。 火紅的嫁衣襯著肌膚如雪桦踊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天终畅,我揣著相機與錄音籍胯,去河邊找鬼竟闪。 笑死,一個胖子當著我的面吹牛杖狼,可吹牛的內(nèi)容都是我干的炼蛤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼本刽,長吁一口氣:“原來是場噩夢啊……” “哼鲸湃!你這毒婦竟也來了赠涮?” 一聲冷哼從身側(cè)響起子寓,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎笋除,沒想到半個月后斜友,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡垃它,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年鲜屏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片国拇。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡洛史,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酱吝,到底是詐尸還是另有隱情也殖,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布务热,位于F島的核電站忆嗜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏崎岂。R本人自食惡果不足惜捆毫,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冲甘。 院中可真熱鬧绩卤,春花似錦、人聲如沸江醇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫁审。三九已至跋炕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間律适,已是汗流浹背辐烂。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工遏插, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纠修。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓胳嘲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親扣草。 傳聞我的和親對象是個殘疾皇子了牛,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354