回退(Rollback WorkItem)
回退是工作流參與者對自己“待辦任務”(實際是對工作項)的一種操作,即參與者主動回退待辦任務列表中的任務到已經執行過的人工節點。
為什麼要回退?
參與者接受任務後,發現不應由自己辦理此任務或以前的執行者辦理有錯誤等情況後,需要將此接受的任務回退給以前某個節點的執行者重新辦理。
回退模式
回退的情況實際上是非常複雜的,其中包括了參與者的重新選擇以及回退的條件判斷等等。這裏先列出常見的回退模式(其實也是我們支持的模式)。
串行
<!-- [if gte vml 1]> <![endif]-->
這種情況最為簡單,後續節點可以回退到前續任意人工節點。回退後,節點重走。
分支
<!-- [if gte vml 1]> <![endif]-->
這種情況也相對簡單,實際執行的分支上的節點可以回退到前續任意人工節點(不區分主支和分支)。同樣,主支上的節點也可以回退到任意實際執行的分支上的節點。
可能的問題:多次回退後的回退節點選擇。例如:第一次流程經過節點2、節點3到達節點5, 節點5可以回退到節點1、節點2和節點3的任意一個,此時節點5回退到節點1,節點1重走,這一次流程改為經過節點4到達節點5,節點5回退時如何選擇回 退節點?此時的策略是以最近實際執行的分支為準,即節點5只允許回退到節點4和節點1,不允許回退到節點2和節點3。(抹去記憶)
併發
<!-- [if gte vml 1]> <![endif]-->
對於併發的情況,分支節點只允許在分支的節點間回退。
<!-- [if gte vml 1]> <![endif]-->
同理,主支節點也只允許在主支的節點間回退。
多實例匯聚
<!-- [if gte vml 1]> <![endif]-->
在這種情況下,節點5會產生2個實例,實際相當於繼續併發。節點5根據具體哪個節點觸發的它而產生回退節點。同時不允許回退到節點1以及前續的節點去。
子流程
<!-- [if gte vml 1]> <![endif]-->
支持子流程到父流程的回退,也支持父流程到子流程節點的回退。需要注意的是子流程節點有可能產生多個子流程實例,在這種情況下不支持父子流程之間的相互回退。
回退節點的參與者選擇
默認策略是由原先節點的實際參與者重新處理,比如節點2回退到節點1,則節點1的實際參與者重新處理該節點任務。這也符合大多數實際的業務場景。
在節點任務競爭參與的情況下,提供另一種策略,即讓人員重新競爭。
回退的條件判斷
對於多人(或者多部門,用户)參與的工作項,提供不同的回退策略
任意人回退即回退,剩餘工作項手工終止
最後提交人回退才回退
關於業務補償
業務補償是一個很重要的概念,在回退的情況下需要相應的回退部分業務操作。這裏由引擎提供統一的接口,返回回退路徑,由客户自定義代碼進行匹配處理。
關於實現
很多工作流引擎通過流程定義時繪出回退線來顯式的支持回退,這種實現在業務複雜的情況下會造成流程圖的異常煩瑣,但是比較清晰,實現比較容易。隱式實現相比而言優點更多。