1. 程式人生 > >activiti工作流引擎多版本方案

activiti工作流引擎多版本方案

activiti流程多版本共存問題

過去使用jbpm4,有一個非常大的問題:

就是當流程發生變化需要部署新版本的時候,由於舊版本有例項在執行中,不能直接覆蓋舊版本的流程,必需新舊(兩個甚至多個版本)共存。而jbpm4本身沒有處理多版本共存過渡到機制,而需要通過自行封裝新增屬性值來描述版本號,這導致封裝沒有完善的情況下,多版本並行機制幾乎不可用。

activit5 已經考慮到多版本問題,即同一個流程,多次部署後會自動產生新的流程標識號並帶上版本ID,如

原版本流程標識號為 testExample:1:201
修改流程配置並部署後,即會自動變更為 testExample:2:301

由此,通過

runtimeService.startProcessInstanceByKey("testExample").getProcessDefinitionId();

可以獲取到testExample:2:301這個ID,即可分離出2這個版本號
而通過自定程式碼組織的協議約束,如規定testExample.java打包位置


package com.yudean.timss.flows.testExample.rX

其中rX的X為版本號,即testExample目錄有r1和r2兩個子目錄,裡面都分別有testExample.java這個處理類
而其他呼叫程式根據獲取到的版本id,可同IoC在執行時才例項化對於版本下的處理類(r1.testExample或r2.testExample)


這樣還有一個問題:

如何區分upgrade流程和update流程

  • 所謂upgrade,即業務邏輯已經發生變化,譬如從3個處理節點,變化成4個,譬如節點的邏輯已經不一樣;
  • 所謂update,即流程只是略有變化,譬如字面的變化(“總經理審批”變更為“總經理稽核”),流程邏輯沒有發生變化。

upgrade流程通過正常的部署流程方式,會自動增長一個版本,然後通過之前說的方式,有對應的新版本的處理程式碼,這是我們想要的效果;
但是如果是update流程,通過正常部署增長了一個版本,但實際上業務處理的邏輯程式碼是完全不需要變更的,那我們為了遷就版本+1的情況而需要複製一份完全一樣的程式碼對於新版本,這樣不單造成程式碼冗餘,還造成簡單修改流程需要變更程式碼重新編譯部署,增加了維護成本。

再考慮這樣一個場景:

業務需求有變更,流程A要從r1升級到r2,部署到測試環境,變成r2,測試後發現bug要修改,並重新部署,版本自動變為r3,最終測試通過部署到生產環境,但生產環境版本號為r2了,兩個環境的版本不對應,而為了兩個環境都能正常跑,則需要有r2,r3兩套完全一樣的程式碼。

這也可以歸納為update和upgrade的問題。

網上有這樣一種方法:

there is a SetProcessDefinitionVersionCmd class you can use to change
the process version on a process instance. It's not “smart”, though;
it simply changes the version number, and doesn't change any other
runtime data

即可封裝一個update的操作,通過呼叫SetProcessDefinitionVersionCmd 來強制不升級流程版本號,此方法尚未證實可行性,但也不失為一個參考。

另一種解決辦法:
建立版本對應表,即我們自定義一個流程版本號,並且與activiti的原生版本號作對映,場景如下

  1. 設定activiti的原生版本號為r,我們自定義的版本號為v;
  2. 初始化一條流程的時候,它是r1版本,對映表中r1->v1,即對應使用程式碼中v1標識的包來處理業務邏輯;
  3. 開發測試過程有變更(屬於update),部署後變成r2,對映表中增加r2->v1,因此對應的處理程式碼還是v1標識的包,程式碼當然有對應更新了。
  4. 部署到生產後,實際版本是r1,對映表r1->v1;
  5. 使用過程中,業務人員提出變更某個環節名稱,但處理邏輯不變更(屬於update),則部署更新流程版本去到r2,對映表增加r2->v1,則依然使用v1包來處理。
  6. 隨著推廣使用,管理層提出優化流程,整個審批流作了精簡(屬於upgrade),此時部署更新了流程版本去到r3,並且需要不同的程式碼處理,因此對映表增加r3->v2,並部署v2的程式碼包。