李飛躍,張 敏,王 偉
(成都工業學院 計算機工程系,成都 610031)
工作流概念起源于JCL(Job Control Language,作業控制語言),其目的是讓用戶定義一組由工作步驟組成的工作流程。隨著信息技術的發展,要求考慮工作流執行原子性和工作流隔離問題,即與工作流事務屬性相關的問題。為解決這一問題,重點放在工作流隔離請求描述以及如何在工作流管理系統中強制執行這些請求。改進并行控制方法,該方法的指導思想是:1)不過分加重工作流設計者的負擔;2)用現有數據庫系統的服務就可以實現。
為此,筆者提出了自我隔離工作流概念。這種工作流采用與傳統事務獲得和釋放鎖相似的方法來設置和取消約束。數據約束用來控制對數據項的修改,任務約束用來控制任務背后程序的執行。這2種類型的約束都能用SQL(Structured Query Language,結構化查詢語言)的斷言表示,而且還能用數據庫系統中的服務強制執行。通過控制對數據庫的接入實現工作流的交替執行與限制任務的執行。
制造工作流包含重復、可預期和復雜處理。衡量工作流隔離好壞的標準是工作流的順序執行,但對執行時間很長的活動來說,順序執行要求過分限制了系統的性能。顯然,工作流隔離(原子執行性)應是在下述之間的折衷:1)工作流執行的正確性;2)工作流系統的性能;3)工作流規范和定義的簡單性。
在工作流并發控制中,充分的隔離請求包含如下條件:1)保證某個屬性的值在一定的范圍;2)不能刪除某元組;3)某類型的元組數量是受限制的。
本文采用與傳統并發控制中的鎖同樣的方法來進行一致性約束。當在并發控制中使用一致性約束時,稱為數據約束。數據約束是由工作流實例創建和刪除的,數據約束特定于某個實例,由工作流或任務實例的輸入參數時產生。因此,一個給定工作流的不同實例可能會設置不同類型的數據約束,這種特點使得自由數據約束成為可能。
獨立于對象自身的約束,控制程序執行的約束稱為任務約束。數據和任務約束都在工作流描述中給出,工作流實例依據描述設置約束和刪除約束。具有這種特點的工作流即為自我隔離工作流。
SQL將斷言描述成由程序員指定的事件觸發,使用斷言能在屬性的值、整個關系、幾個關系間的關聯上定義約束。斷言創建格式為:CREATE ASSERTION <name>CHECK <condition>。
本文中工作流隔離請求使用斷言表示,1個工作流實例傳送1個斷言請求給SQL系統,系統接受或拒絕該請求。
自我隔離工作流設置和取消數據與任務約束。每個約束依附于1個工作流單元,即1個工作流、子工作流或1個任務。在特定的任務中設置附屬于1個工作流單元的全部約束稱為設置隔離,相應地在取消隔離任務中取消全部約束。含有這種額外任務的工作流單元稱為已隔離工作流單元。在圖1中用大寫字母U來表示這種已隔離工作流單元。

圖1 已隔離工作流單元U
1.3.1 表達數據約束
設置隔離任務是設置一個或者多個約束的事務。如果斷言在數據庫中是無效的,則設置斷言失敗。通常,每個斷言生成一個關系且只有該關系為空時斷言才是有效的。
為演示數據約束的使用,考慮貸款請求工作流的隔離問題,筆者將演示使用任務約束如何解決該隔離問題。
貸款請求工作流隔離問題是指依據在貸款檢查約束中取得客戶已有貸款的情況下決定要不要放款。設置隔離和請求隔離任務使用貸款請求工作流的輸入參數,假定貸款請求有3個輸入參數:W_CNO,W_CNM,W_LA。因此,激活貸款請求工作流可以通過調用函數Loan_request(12345,LFY,100000)實現。
現在設置隔離任務包含名為LoanIsolation(載入隔離)的事務。

圖2 貸款請求處理工作流

表1 活動貸款請求關系
Proagam SetLoanIsolation(W_CNO,W_CNM,W_LA)
Begin Transaction
INSERT INTO ActiveLoanRequest
VALUES(:W_CNO,:W_CNM,:W_LA)
CREATE ASSERTION <system generated name>
CHECK1=(SELECT COUNT(*)FROM ActiveRequest WHERE cno=:W_CNO);
End Transaction
首先,載入隔離事務試圖插入一個元組到關系ActiveLoanRequest(活動貸款請求)中(如表1所示)。如果客戶已經有一個活動貸款請求存在的話,則存在一活動斷言使得在ActiveLoanRequest中的插入失敗,這反過來意味著設置隔離失敗,否則,創建斷言成功。
取消隔離事務如下:
Proagam UnSetLoanIsolation(W_RequestNumber)
Begin Transaction
DROP ASSERTION <system generated name>
DELETE FROM ActiveLoanRequest
WHERE RequestNumber=:W_RequestNumber;
End Transaction
在上面的例子中,筆者強制執行斷言限制特定類型的元組數量。
1.3.2 管理數據約束
比起傳統的鎖來講,在調度自我隔離工作流時,每個工作流有一個它自己的正確性準則,不需考慮數據約束之間是否有沖突。在管理數據約束[2]中,有必要檢查被請求的數據約束是否與數據庫的狀態存在沖突,如果請求(斷言)與數據庫狀態沖突則拒絕該請求;否則接受該請求。接受一個數據約束請求意味著該約束從接受它的時候開始生效,同時,在數據約束廢棄前數據庫系統將強制執行它的有效性。
系統不用考慮數據約束之間是否有沖突的事實,簡化了執行,減輕了工作流系統的負擔。
工作流系統存儲有關工作流實例能否繼續執行的狀態信息。通過在狀態信息(關系)上設置約束來控制工作流實例的隔離,在狀態關系上設置約束意味著不允許有某特定執行狀態,將這種約束稱為任務約束。
靜態任務約束與動態任務約束的區別是:1)靜態任務約束由工作流設計者建立;2)動態任務約束由工作流實例建立和刪除。
設對每個工作流單元都存在一個稱為任務關系[3]的關系。任務關系的名字與工作流單元的名字相同,屬性由工作流單元的全部或部分輸入參數組成。任務約束的創建和刪除分別在設置隔離任務和取消隔離任務中進行。如果任務約束與任務關系中的狀態沖突的話,創建任務約束就會失敗。與數據約束管理相似,接不接受任務約束是與其他任務約束無關的。
筆者采用任務約束解決貸款請求工作流隔離問題。貸款請求工作流參數有客戶的名字、客戶的編號、貸款的數據。假定存在一個貸款請求任務關系實例(如表2所示)。關系實例表明李四有2個活動貸款請求,而張三和王五各有1個活動貸款請求。
接下來在貸款請求關系中設置靜態與動態任務約束。如設置一個靜態任務約束,不允許2個元組具有相同的客戶編號來解決貸款請求并發問題。用下面的SQL語句實現:

使用動態任務約束[4-5]能描述更精細的隔離請求,例如,在開始處理王五的貸款請求時可能會在與貸款檢查子工作流相應的任務關系上設置任務約束,該約束限定客戶編號屬性為12的元組最多只能有1個。可用如下語句實現:


表2 貸款請求關系
自我隔離工作流在數據庫的數據項或任務狀態信息上設置約束來實現工作流并發控制。數據約束與任務約束都能用SQL語言的斷言進行表示。通過SQL斷言的表達能力能指明隔離工作流隔離請求,減輕了工作流設計者描寫選項和約束的負擔,實現起來也很容易。
[1]JEFFREY D U.數據庫系統基礎教程[M].3版.北京:機械工業出版社,2009.
[2]劉慧,王寧,劉元元,等.一種基于約束的事務工作流并發控制方法[J].計算機系統應用,2011(12):181-184.
[3]劉兵兵.一類帶延遲策略的庫存優化模型及其仿真[J].計算機應用,2009,29(10):2762-2765.
[4]胡國玲.分布式移動代理系統的事務管理及死鎖檢測研究[J].微電子學與計算機,2007,24(10):146-149.
[5]郝麗波,李建華.基于隔離域的事務工作流并發控制[J].計算機工程與設計,2008(1):199-202.