簡體   English   中英

Activiti並行服務任務

[英]Activiti parallel Service Tasks

我正在嘗試在Activiti中實現兩個應該並行運行的服務任務。 下面編寫的代碼可以隨機(且有趣)地正常工作。

我的意思是,它偶爾只打印“ first ”(或“ second ”),或者只打印兩個“ first ”(一個)“ second ”(等)。

問題:如何使這些服務不斷並行運行? 不管當前正在運行的服務數量是多少?

PS:當我從流程定義中刪除activiti:async="true" ,它僅打印“ first ”或“ second ”。 我想我需要:)

工藝定義

<?xml version='1.0' encoding='UTF-8'?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn" targetNamespace="Examples">

    <process id='testparallelact' name="Developer Hiring" isExecutable="true" activiti:exclusive="false" activiti:async="true">

        <startEvent id="theStart" />
        <sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" />

        <parallelGateway id="fork"  activiti:async="true" />
        <sequenceFlow sourceRef="fork" targetRef="receivePayment" />
        <sequenceFlow sourceRef="fork" targetRef="shipOrder" />


        <serviceTask id="receivePayment" name="Receive Payment" activiti:async="true" activiti:exclusive="false"
activiti:expression="${serviceConnections.runThis2('First')}"/>

        <sequenceFlow sourceRef="receivePayment" targetRef="join" />


        <serviceTask id="shipOrder" name="Ship Order" activiti:async="true" activiti:exclusive="false"
activiti:expression="${serviceConnections.runThis2('Second')}"/>

        <sequenceFlow sourceRef="shipOrder" targetRef="join" />

        <parallelGateway id="join" />
        <sequenceFlow sourceRef="join" targetRef="theEnd" />
        <endEvent id="theEnd" />
    </process>
</definitions> 

流程定義的圖形呈現

流程定義的圖形呈現

代碼為“ runThis2”

public void runThis2(String test1) throws InterruptedException {            
    while(true)
    {
        Thread.sleep(1000);
        System.out.println(test1);              
    }           
}

“異步”和“排他”標志的組合很重要

了解作業如何在Activiti引擎內執行非常重要。 以下論壇線程在描述它方面做得很好:

https://community.alfresco.com/thread/221453-multiinstance-wont-run-task-in-parallel

Activiti最初的一位建築師Tijs Rademakers的摘錄於2013-10-25:

例如,並行網關和多實例構造能夠並行運行多個用戶任務。 但是對於服務和腳本任務,它們基本上還是串行執行的。 如果您還將獨占設置為false(默認值為true),則異步可以更改此行為。 然后,作業執行程序將只執行所有可用的作業,而不是順序執行。 因此,請嘗試將async設置為true,將exclusive設置為false。

現在,通過設置activiti:async="true"activiti:exclusive="false" ,您有效完成的工作是通過將服務任務(通常是串行處理)分配給Job Executor來在流程中創建“等待狀態”。

但:

  • 並行執行多少個作業,
  • 它們由Job Scheduler執行

現在完全由Job Executor配置控制。 (線程池的大小,超時,並發作業數,作業塊的大小都是可配置的。)

現在,這並不完全符合您的期望,這取決於您的作業隊列的大小,一次掃描中有多少個作業以及每個作業的執行時間以及執行服務任務的時間。 意思是,它們可能並行執行,並且可能串行執行。 同樣,您無法控制他們的訂單,因為再次由求職執行者來決定其工作和時間。

好的,假設這符合您的要求...

樂觀鎖概念

...您可能還會遇到另一個問題(實際上,這是首先引入activiti:exclusive標志的原因)。 服務任務完成后,執行上下文將提交給數據庫中的流程實例記錄以及歷史記錄。 為了性能起見,Activiti使用“樂觀鎖定”進行記錄。

現在,如果您的進程分支在時間上相對接近彼此完成,那么(實際上很有可能)您將在數據庫更新中收到Optimistic Locking Exception ,如下所示:

09:59:52,432 [flowable-async-job-executor-thread-2] ERROR org.flowable.job.service.impl.asyncexecutor.DefaultAsyncRunnableExecutionExceptionHandler - Job 12575 failed org.flowable.engine.common.api.FlowableOptimisticLockingException: ProcessInstance[12567] was updated by another transaction concurrently

(注意:上面的錯誤實際上不是來自Activiti的,而是來自名為“ Flowable ”的項目。但是,在最初提出此問題時,它們兩者都具有與Activiti 6相同的代碼庫。(2017年11月)。)

這將導致服務任務被標記為FAILED並將被重新嘗試 如果您要外部調用SOR(記錄系統)或其他舊系統,則可能會出現問題。 (考慮會發生什么,如果你的航班實際上是成功預定,但調用保留它是由第二次,因為它被認為已經失敗。)

好的設計和使用的最佳實踐可以解決所有好玩的東西。

希望這可以幫助您了解發生了什么。

格雷格@ BP3

進一步閱讀

Alfresco論壇帖子包含幾個無效鏈接。 以下是實時鏈接。

遺留問題跟蹤鏈接

補充說明:Activiti當前(2019)不再使用這兩個(codehaus.org或atlassian.net)跟蹤器。 相反,他們使用此GitHub跟蹤器: https : //github.com/Activiti/Activiti/issues

常見問題解答鏈接

Activiti標志

卡蒙達手冊

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM