最近在使用Camunda工作流引擎實現微服務的編排工作,根據業務場景需要某些任務節點在出現異常的情況下,進行異步重複操作,且不能影響之前節點的執行結果,即事務不能回滾。配置好工作流程後,本以爲可以順利執行,結果出現Camunda JOB 沒有執行的情況,流程停留在時鐘節點上。該問題耗費了兩天的時間才解決。
環境版本說明:
camunda-bpm-spring-boot-starter-webapp 3.0.5
spring boot 2.2.5.RELEASE
Oracle 數據庫 ojdbc的版本:11.2.0.3.0
示例流程圖如下:
“任務二”節點在出現異常情況情況下,拋出了BpmnError給流程引擎,這時Camunda流程引擎應該捕獲該該錯誤,然後通過JOB Executor 進行異步調度執行,但是這個調度任務並不起作用,節點卡在了時鐘節點上,且不再繼續執行。
是什麼原因導致的呢?怎麼解決呢?
經兩天的源碼調試和分析,發現調度任務不起作用的主要原因是Camunda Job Executor 在執行任務前,需要對任務添加樂觀鎖,但是每次加鎖都是失敗的,如圖:
numberofJobsFailedToLock = 1, 而acquiredJobs Size 爲0.在調試的期初,acquiredJobs是大於0的,這說明加鎖是失敗的,之前獲取的需要執行的JOB任務被移除了,那麼爲什麼會加鎖失敗呢?需要找到執行樂觀鎖的SQL纔行,執行的SQL如下:
這個時候我們發現,返回值爲【-2】,Camunda流程引擎對於【-2】這個值,認爲是加鎖失敗的,這是就主要的原因了。
因爲Camunda工作流引擎默認採用的是批量操作的方式,而我們使用的Oracle數據庫版本爲11.2。根據Oracle官方的解釋,該版本在執行批量操作的時候,即使執行成功,但是不能正確返回執行成功的記錄數,這個時候返回值爲【-2】
好了,找到了本質的原因,想要解決這個問題,就需要關閉Camunda工作流引擎批量操作的方式.
方式一,在yml文件中添加配置,關閉批量處理操作:
方式二:使用Camunda的ProcessEnginePlugin 插件修改流程引擎的配置
經過測試,問題解決了。
總結:由於Oracle數據版本的問題,Camunda流程引擎中的採用批量操作都會被影響,如果希望使用Camunda的批量操作提升性能,Oracle需要採用12.* 以上的版本。
參考文檔:
https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#executeBatch()
https://docs.camunda.org/manual/latest/user-guide/spring-boot-integration/configuration/