王鈞召,江學武,何云峰,于俊清*
(1.廣東粵電信息科技有限公司,廣東 廣州510630;2.華中科技大學計算機科學與技術學院,湖北 武漢430074)
工作流技術越來越廣泛地應用在企業信息系統中,大部分企業信息系統都選擇采用成熟的商業或開源的工作流產品,也有不少企業在原有信息系統基礎上進行二次開發,實現符合自身需求的工作流管理系統(WfMS,Workflow Management System)[1-3]。商業工作流產品,國外主要有IBM 公司的Lotus Domino Workflow 和WebSphere MQ Workflow,以及Oracle 公司的Oracle Workflow 等工作流產品[4]。國內目前比較流行的WfMS,主要有西安協同的SynchroFlow,上海東蘭的DLFlo 和杭州信雅達的SunFlow 等[5]。國外的工作流產品并不適合用于管理具有中國特點的業務流程,因此大部分企業都采用國內廠商生產的工作流產品,維護和升級比較方便。目前使用較多的開源工作流產品,主要有jBPM(Java Business Process Management,jBPM)和Activiti。jBPM[6-7]提供了工作流引擎和應用擴展接口,可以根據不同需求進行功能擴展,能夠方便地集成到已有的系統中。Activiti[8-9]的發起人是原jBPM 創 始 人Tom Baeyens,Activiti 是 在jBPM3 和jBPM4 的基礎上發展而來的,其內部接口與核心API與原jBPM 有很多的相似之處。Activiti 與jBPM 相比較,增加了流程可視化與管理能力,并加強了與外部系統的集成能力。
功能完備的工作流產品除了支持基本的業務操作之外,還支持“撤銷”,“委派”,“會簽”以及“自由流”等復雜業務場景,實現比較復雜,如果要集成到原有的信息系統中,需要修改相關代碼和配置相關文件,才能方便對接。但是,發電企業燃料管理中的很多業務流程只需要基本的“通過”和“退回”功能,如果采用成熟的商業或開源工作流產品,將造成成本較高、集成復雜和系統兼容性差等問題。
為了能夠方便地集成到已有的信息系統解決簡單的業務流程定制,設計了輕量級的工作流管理系統[10],并將系統應用到火力發電企業燃料信息系統的審批流程中,實際應用結果表明,該系統可以滿足信息系統中對審批流程自動化流轉的要求,能夠保證審批流程的正確運行。
根據WfMC 給出的工作流管理系統參考模型[11],輕量級工作流管理系統的總體架構如圖1所示。

圖1 工作流管理系統總體架構圖Fig.1 System architecture of WfMC
工作流管理系統主要由工作流定義工具和工作流引擎組成。其中,工作流定義工具以圖形化的方式為用戶提供抽象實際業務流程及描述流程的手段,同時生成工作流模型,這里的工作流模型是指可被計算機處理的形式化定義,是由組成工作流的各個活動以及活動之間的關聯關系等信息組成的一個完整的數據結構,通常被保存在數據庫中。工作流引擎將數據庫中保存的工作流模型作為依據,驅動工作流實例的自動流轉[12]。
根據WfMC 規范,工作流定義工具由3 部分組成:模型設計器、工作流模型和模型控制器。
模型設計器用于定義工作流模型,通過拖拽相關組件進行流程圖的繪制,鼠標點擊和鍵盤輸入操作可以設置各個活動的可操作角色,用戶做出的各種請求動作將由模型控制器響應。用戶定義工作流模型之前,流程設計器先查詢該工作流模型是否已存在,如存在則在原有模型的基礎上進行更改。
工作流模型既可以保存為XML文件,也可以保存在數據庫中,作為工作流實例自動流轉的依據。輕量級工作流系統通過工作流表、節點表、節點間連線表、工作流實例執行情況表4個數據表保存每一個工作流模型各個節點的信息和節點間連線信息,以及工作流實例的運行情況。
模型控制器負責響應模型設計器的請求動作,主要功能包括:圖形化界面中各個組件的增刪改查,工作流模型與XML 文件的相互轉換,數據庫的存取,以及一些其他操作如清空、撤銷等。模型控制器中還提供一個重要功能,就是工作流模型的合理性驗證。對工作流模型的合理性驗證分為語法驗證、語義驗證和結構驗證[13]。由于語義驗證由工作流模型設計人員負責驗證,所以驗證功能只提供語法驗證和結構驗證。
工作流引擎需要對定義的工作流模型進行解析,讓計算機能理解該模型的具體含義,驅動工作流實例按照該模型進行正確流轉,它是工作流管理系統的核心組成部分[14]。對于每個工作流實例來說,各項任務能夠按照工作流模型進行自動流轉并且互不干擾,都是因為工作流引擎在后臺進行控制。工作流引擎的工作流程如下:
1)用戶啟動某個工作流實例,該實例開始執行;
2)工作流引擎從數據庫中讀取對應的工作流模型;
3)當用戶對某個節點操作完成,工作流引擎決定該實例的流轉方向,即決定下一個操作節點以及該節點可操作的角色,一直持續到該實例流轉結束。
工作流引擎以工作流模型作為依據,根據控制參與者的操作權限和工作流實例的執行情況控制實例的正確流轉。
定義的工作流模型是否合理直接決定了工作流實例能否正常執行,因此工作流模型的合理性驗證至關重要。工作流模型的合理性驗證分為語法驗證、語義驗證和結構驗證[15]。語法驗證提供初級的錯誤驗證,主要驗證是否有重名的節點,是否有孤立的節點,每個節點是否都存在輸入狀態和輸出狀態等。語義驗證用于驗證工作流的定義是否與實際業務流程的目標相同,由工作流模型設計人員負責。結構驗證檢查是否存在非法并發、死循環等錯誤,這里重點說明結構驗證。
工作流模型存在唯一的開始節點和結束節點。工作流模型可以看作有向圖,該有向圖必須是連通圖,不能存在多個連通子圖。因此從開始節點進行遍歷必須能遍歷到所有的節點,否則存在節點不可達的錯誤。工作流模型中可能存在非法并發單元,主要表現為非法入口,非法出口和并發跳轉等。工作流模型組成元素包含:開始節點、結束節點、流程節點以及節點間連線。各個元素的圖形化表示如圖2所示。

圖2 工作流模型組成元素表示圖Fig.2 The legend of Workflow engine
常見的結構性問題主要有以下幾個方面:
1)節點不可達;指對于某一個節點,無法從開始節點找到一條路徑到達該節點,如圖3(a)所示。如果存在不可達的節點,那么該節點的存在是無意義的,因為在工作流實例的執行過程中,該節點永遠不會得到執行。
2)非法并發單元:非法并發單元是指存在錯誤的并發單元,錯誤原因包括非法出口、非法入口和分支跳轉。
非法出口,是指存在某條路徑,可以從并發單元內的某個節點直接到達并發單元外的某個節點。如圖3(b)所示,一個有非法出口的并發單元由并發單元內的流程節點B可以直接到達并發單元外的流程節點E。
非法入口,是指存在某條路徑,可以從并發單元外的某個節點直接到達并發單元內的某個節點。如圖3(c)所示,一個有非法入口的并發單元由并發單元外的流程節點A可以直接到達并發單元內的流程節點C。
分支跳轉,是指存在某條路徑,可以從某個分支直接到達同一個并發單元中的另一個分支。如圖3(d)所示,一個分支間存在跳轉的并發單元由并發開始節點A有兩條完全不重合的路徑可以到達并發單元內的流程節點C。
3)其他錯誤:其他可能出現的結構錯誤如圖3(e)所示,一個并發單元的并發開始節點A 可以直接到達并發結束節點D;又如圖3(f)所示,由流程節點A,B,C,D組成了一個環,工作流實例一旦進入該環中,將一直在流程節點A,B,C,D之間循環執行,系統產生死循環,導致工作流實例不能正常結束。
工作流模型可以看做是一個有向圖,利用深度優先搜索的思想,對該有向圖進行遍歷,能夠檢測出存在的結構性錯誤。結構驗證算法基于矩陣模型和深度優先搜索,能夠檢測出典型的結構性錯誤。該算法的流程圖如圖4所示。
1)初始化變量。
初始化節點總數n,并規定開始節點的編號為0,結束節點的編號是n-1,其他節點編號按照層次遍歷的順序從1 開始逐一遞增。初始化矩陣變量matrix[n,n],visit[n,max]和info[n,3]。其中:

matrix[n,n]表示工作流模型中的節點間關系。visit[i,j]表示節點i到j之間的邊執行情況,0表示未執行,1表示已執行,工作流實例執行之前所有的邊都是未執行的。info[i,0]表示節點i是否已遍歷,0表示未遍歷,1 表示已遍歷;info[i,1]表示節點i 入邊個數,info[i,2]表示節點i的出邊個數。
2)驗證節點可達性。
通過遞歸算法遍歷節點,驗證info[0...n-1,0]是否都是1,如果存在0的情況,假如info[i,0]為0,那么說明無法找到一條路徑從開始節點到達節點i,即存在不可達節點;如果info[0...n-1,0]都是1,則驗證通過。接下來驗證第二部分,采用相同的算法,但是傳入參數matrix 時,選擇傳入他的變形矩陣antiMatrix[n,n],其中:

驗證從結束節點能否逆向到達所有節點,即驗證對于每一個節點都能至少找到一條路徑能到達結束節點。

圖3 結構性錯誤實例Fig.3 Examples of structural errors

圖4 結構驗證算法流程圖Fig.4 Flow chart of structure verification algorithm
3)驗證是否存在非法的并發單元、死循環等錯誤。
并發單元的驗證主要依據并發單元的并發入口和并發出口的一對一的關系,且并發入口先于并發出口出現。因此,如果發生以下情況,則說明存在非法并發單元:并發出口先于并發入口出現;并發入口對應多個并發出口,或并發出口存在多個并發入口;并發入口與并發出口直連。
為了達到上述驗證目的,定義了一個遞歸函數,其偽代碼如下:
Algorithm 1:結構性驗證算法
Input:
id:當前遍歷節點的編號,初始為0
matrix[n,n]:該有向圖的鄰接矩陣
info[n,3]:info[i,1]表示節點i 入邊個數,info[i,2]表示節點i的出邊個數
dict[key,val]:dict中保存了所有的并發單元入口,并發單元出口的鍵值對[key,val]
stack:保存并發單元入口
Output:
errorInfo:記錄可能發生錯誤的節點編號
1:if(info[i][2]>1)then
2:curKey ←id//curKey表示當前并發單元入口
3:if(dict中不存在curKey)then
4:dict ←[curKey,-1]
5:curKey入棧stack
6:endif
7:endif
8:if(info[id][1]>1)then
9:curVal ←id//curVal表示當前并發單元出口
10:if(dict中存在curKey)then
11:if(dict[curKey]不存在對應的val)then
12:dict[curKey]←curVal
13:if(并發入口與并發出口直連)then
14:errorInfo ←curVal//出現錯誤
15:endif
16:curKey 從stack 出棧//表示當前并發單元入口已找到出口,配對完成
17:else if(dict[curKey]!=curVal)then
18:errorInfo ←curVal//當前并發單元入口,存在多個出口,出現錯誤
19:endif
20:else then
21:errorInfo ←curVal//當前并發單元出口,不存在入口,出現錯誤
22:endif
23:endif
24:for(與節點id存在聯系的所有節點i)
25:if(節點id到節點i之間的邊未遍歷過)then
26:遞歸調用本算法,其中參數id傳入i
27:endif
28:endfor
根據文獻[16]中的相關表述,表1 中對常見的工作流結構驗證算法進行了比較。其中N/A表示無法從文獻中獲知。

表1 結構驗證算法比較表Table1 Structure verification algorithm comparison table
由表1可知,相比其他算法,本算法可以驗證節點不可達、非法并發以及死循環等常見的結構性錯誤,算法的時間復雜度不高,并且實現相對簡單。
火力發電企業燃料信息系統中,存在很多審批流程,審批流程中存在多個環節,這些環節的操作都是類似的,只是操作順序或者操作角色不同。隨著需求的變動,審批流程需要經常變更,系統開發人員需要針對流程的變更,更改原先的審批流程代碼,給系統帶來了不穩定性,也增加了開發人員的負擔。因此針對這種情況,設計了工作流管理系統,該系統可以自動控制審批流程的自動流轉,即使更改審批流程,也不需要系統開發人員更改代碼,從而保證了系統的穩定性。
管理員設計工作流的具體執行步驟,即定義工作流模型,定義結果將保存在數據庫中,作為工作流實例自動流轉的依據。模型設計器的工具欄中,提供了組件繪制功能,通過鼠標的點擊和拖拽動作便可完成設計,工具欄中還提供了清空,撤銷和與XML 文件相互轉換等輔助功能。模型設計器界面如圖5所示。

圖5 模型設計器界面示意圖Fig.5 Workflow engine designer interface
工作模型在保存之前,將進行合理性驗證,如果通過驗證則保存到數據庫中,否則不予保存。如果審批流程需要變更,只需更改在模型設計器中做簡單調整即可,不需要對系統代碼進行更改,但是之前正在執行的工作流實例必須重新開始執行。
由具有指定權限的用戶“提交”審批,之后便啟動了一個合同審批流程的實例,該實例按照已定義的工作流模型開始執行。對于系統中所有相關用戶,都存在一個待處理審批流程頁面,當某個工作流實例流轉到該用戶可處理的節點時,頁面就會顯示這個工作流實例,該用戶就能對這個實例進行審批操作。在審批過程中,可以看到工作流的詳細執行情況,如圖6 所示,在已執行節點上可以顯示該節點歷史執行記錄,頁面右側顯示了該工作流實例的歷史執行情況。

圖6 某工作流實例執行情況界面Fig.6 Workflow instance execution interface
企業中某些業務流程只需要基本的“通過”和“退回”功能,如果采用成熟的商業或開源工作流產品,將造成成本較高,集成復雜以及系統不兼容等問題,本文針對這類簡單的業務流程設計和實現了輕量級的工作流管理系統可以有效解決該問題。由于設計的工作流管理系統在工作流模型定義,模型結構性驗證方面存在一定的局限性,未來可以在模型設計器中,增加“或分支”功能,用于指示工作流中的并發單元是條件選擇關系,還是并發執行關系。