三、在工作流中使用事務
WF提供的TransactionScopeActivity封裝了.NET System.Transactions的事務功能,可以在操作發生錯誤時自動復原,進而支援從事務失敗中恢複。請參考MSDN中擷取System.Transactions.Transaction和System.Transactions.TransactionScope類的更詳細資訊。
工作流中的批處理狀态資訊
工作流會周期性在各個檢查點儲存它有狀态,如果發生錯誤,工作流引擎有必要檢索儲存過的資訊來傳回到一個穩定的狀态。如果兩個以上的元件正在通信,那麼元件間的coordinate persistence有助于保證元件的一緻性。
這一點在發送或接收消息時尤其有用。例如,一個工作流可能發送多條消息,每個發送的操作都會請求消息服務。消息服務必須要維護工作流的一緻性和持續的狀态,隻有工作流狀态被成功儲存,消息才能被發送。這意味着在單個的事務中,工作流狀态以及消息發送狀态都會被儲存起來,以儲存所有元件間狀态的一緻性。
WF提供了System.Workflow.Runtime.IWorkBatch 和 System.Workflow.Runtime.IpendingWork兩個接口來解決這個問題。
在對服務所有調用中,運作時引擎在自己的線程上下文中提供了System.Workflow.Runtime.IworkBatch,你可以添加一個挂起的工作項到批進行中,這樣運作時引擎可以一次性将所有相關的工作項送出到事務處理。
在ExternalDataEventArgs的構造函數中,可以傳遞一個IpendingWork類型的參數。
當元件被請求時的執行順序
1、在第一次請求前,工作流建立工作批處理對象。
2、工作流将工作批處理傳對象遞到到元件的請求方法中。
3、元件建立一個工作項,并将其添加到工作批處理對象中。
其它元件請求時,重複第二步和第三步。
在事務送出點的執行順序
1、工作流建立一個事務
2、工作流周遊工作批處理對象中的工作項,并收集其中屬于某一元件的工作項,維護其順序,然後建立一個新工作批處理對象。工作流調用元件的Commit方法,并把事務對象和這個批處理對象傳遞給它。
3、元件把工作批處理對象中的工作添加到事務中。
對所有的元件重複第二步和第二步。
當元件的Commnit方法成功調有後,工作注送出相應的事務。
當事務成功送出後,工作流周遊工作批進行中工作項,如第二步一樣。工作流調用每個元件的Complete方法,交把事務對象和批處理對象傳遞給它。
工作流發生錯誤時的執行順序
1、工作流識别錯誤範圍内的所有工作項并構造一個工作批處理對象,并将這些工作項添加這個工作批處理對象中。對于2、工作批進行中所有工作,工作流通過IPendingWork接口來調用其Complete方法,并傳遞完成狀态為false
3、工作流取消工作批進行中的所有工作。
從錯誤中恢複後,運作時維護剩餘的工作批處理項引用。
WF中的錯誤處理
WF中的錯誤是以異步的方式來處理的。在活動中顯式或隐式的抛出異常後,工作流運作時引擎會将捕捉到的異常先儲存到隊列中,在之後的時間再進行處理。這與一般的異常處理方式不同在于,如果一個異常在try{}語句塊中被抛出,在相應的catch{}語句塊中無法截獲該錯誤,同時該錯誤也不會立即抛出給使用者。
異常的起因
以下幾種情況可能會産生異常
· 原子事務逾時
· 其它類型的事務失敗
· 宿主程式通過ThrowActivity抛出異常
· 使用者代碼錯誤。當工作流調用外部的使用者代碼時,CLR類可能會抛出異常,如果這種異常在使用者代碼中沒有被處理,它們最終會以工作流異常的的表式出現。
· 其它類型的系統異常,例如儲存失敗,.net或系統異常,或資料轉換錯誤等
異常捕獲
錯誤進行中,如果抛出異常的活動不能處理它,異常會被轉交到它的上一級活動處理,直到它被處理為止,否則的話,工作流執行個體就會被工作流運作時引擎終止。
錯誤處理是由FaultHandlerActivity活動來完成的。每個FaultHandlerActivity活動都與一個.net異常類型相關聯,并且它包含一系列的活動,如果錯誤類型與某個FaultHandlerActivity關聯的錯誤類型比對的話,就會執行為個FaultHandlerActivity活動。一個FaultHandlersActivity活動包含0-n個FaultHandlersActivity子活動,FaultHandlersActivity可以是任何複合活動的子活動。
WF中的錯誤處理通常被視為一個反向的工作,因為它的目标是當異常發生時,撤銷活動中不成功的部分的工作。FaultHandlerActivity的執行完成不能被認為是事務活動的成功完成。事務活動會先被設定成錯誤狀态,然後是關閉狀态。任何兄弟活動同樣會被取消。同時,compensation也會成為不可用狀态。
在工作流中使用Compensation(下面譯為補償)
WF中對于已完成事務的補償模式,是對工作流中出現的異常進行處理的過程,并且會在邏輯上撤銷已完成的事務。
WF補償有以下兩種形式:
當異常沒有被處理的時候,系統隐式的補償;
使用Compensate活動進行顯式的補償。
在工作流中使用動态更新
動态更新使得我們可以在工作流執行個體運作的時候對它做出改變。做這些改變,可能是由于設計時候的疏忽,或者是屬性的改變,活動的綁定,或者是業務邏輯得到了加強和完善。如果你需要整個改變工作流,動态更新并不适用,否則會導緻工作流與最初的設計原則完全不同。在這種情況下,你應該設計一個新的工作流。
動态更新适用于工作流的單個執行個體。如果已經有工作流執行個體運作,不能對工作流中的進行類型的改變。
你可以使用動态更新來幹面的事情:
· 改變正在運作的工作流執行個體;
· 改變運作時行為;
· 改變工作流結構,例如,添加或移除一個活動;
· 改變流程控制;
· 為對一個已經存在的活動定義一個新的條件;
· 改變一個PolicyActivity的RuleSet;
· 如果在工作流在已經部署和運作後, 需要在工作流中增加一個新的業務過程,可以通過添加一個新的自定義活動,或InvokeWorkflowActivity活動來實作;
· 添加一個新的EventDrivenActivity來響應一個新的事件,如一個附加的确認步驟;
對一個正在運作的工作流進行動态更新,可能會導緻兩個不同的入口點:一個在工作流代碼檔案内,一個在工作流外,如工作流宿主程式。
工作流中的資料交換
WF通信服務支援在工作流服務環境内的資料交換,它使得工作流可以以方法和事件的形式,與外部系統通過消息進行通信。
WF通過web serivce通信來實作工作流之間的資料交換。
在工作流中使用角色
WF提供了一種基于角色的通路機制,适用于所有支援資料輸入的活動。工作流的建立者有完全的控制權限來建立角色和角色集合。建立者通過這種方式,可以提供一種必要的權限機制,在活動被執行之前,來檢測通路者角色的權限。
有一些WF活動,如WebServiceInputActivity,通過其屬性就可以取得或設定角色集合。
使用活動目錄(Active Directory,),可以使得工作流的開發更加容易,WF通過一種被稱為out-of-the-box的機制,來建立基于活動目錄的角色。請參考MSDN,了解更多關于.net framework和活動目錄的安全機制。
與角色相關的類有WebWorkflowRole,WorkflowRole,ActiveDirectoryRole等等,在System.Workflow.Activities命名空間中。
編譯工作流
工作流可以通過以下三種方式被建立:
通過工作流markup檔案,使用工作流markup,該檔案的字尾為.xoml。通過宿主程式,把該檔案傳入給工作流運作時引擎,這種方式被稱為“無代碼工作流建立”,這種方式下,工作流不需要編譯。被建立的檔案名WorkflowSample.xoml(舉例)
另一種方式是,markup檔案用來聲明工作流,然後與包含邏輯實作的代碼一起被編譯。這種方式被稱為“代碼分離工作流建立”。被建立的檔案名為:WorkflowSample.xoml 和WorkflowSample.xoml.cs
在代碼檔案中使用WF對象模型。這種方式稱為“僅代碼工作流建立”。被建立的檔案名為:WorkflowSample.cs 和 WorkflowSample.Designer.cs,這些檔案會被編譯。
當工作流被編譯時,會執行以下過程:
· 驗證工作流活動是否符合為該活動設定的規則,如果驗證産生錯誤,編譯器會傳回一個錯誤清單;
· 據傳入到編譯器中的标記(markup)定義,建立一個partial類;
· 從标記檔案産生的partial類和人代碼檔案産生的partial類,被送入到.net編譯器,這個過程的輸出結果就是一個.net 程式集。檔案名如:WorkflowSample.dll,可以被部署運作工作流了。
在指令行中使用wfc.exe
WF提供了指令行方式的工作流編譯器,即wfc.exe。WF同樣提供一系列的支援工作流編譯公共類型,可以用來開發自定義的工作流編譯器。這些公共類型也是wfc.exe所用來的類型。你可以通過WorkflowCompiler類來建立一個自定義的編譯器。
你還可以使用WorkflowCompiler類來編譯工作流,例如:
WorkflowCompiler compiler = new WorkflowCompiler();
WorkflowCompilerParameters param = new WorkflowCompilerParameters();
compiler.Compile(param, new string[] { "MainWorkflow.xoml" });
wfc.exe編譯選項
wfc指令行的選項如下
Microsoft (R) Windows Workflow Compiler version 3.0.0.0
Copyright (C) Microsoft Corporation 2005. All rights reserved.
Windows Workflow Compiler Options
wfc.exe <XAML file> /target:codegen [/language:...]
wfc.exe <XAML file list> /target:assembly [<vb/cs file list>] [/language:...]
[/out:...] [/reference:...] [/library:...] [/debug:...] [/nocode:...] [/checktypes:...]
- OUTPUT FILE -
/out:<file> Output file name
/target:assembly Build a Windows Workflow assembly (default).
Short form: /t:assembly
/target:exe Build a Windows Workflow application.
Short form: /t:exe
/target:codegen Generate partial class definition.
Short form: /t:codegen
/delaysign[+|-] Delay-sign the assembly using only the public portion
of the strong name key.
/keyfile:<file> Specifies a strong name key file.
/keycontainer:<string> Specifies a strong name key container.
- INPUT FILES -
<XAML file list> XAML source file name(s).
<vb/cs file list> Code file name(s).
/reference:<file list> Reference metadata from the specified assembly file(s).
Short form is '/r:'.
/library:<path list> Set of directories where to lookup for the references.
Short form is '/lib:'.
- CODE GENERATION -
/debug[+|-] Emit full debugging information. The default is '+'.
Short form is '/d:'.
/nocode[+|-] Disallow code-separation and code-within models.
The default is '-'. Short form is '/nc:'.
/checktypes[+|-] Check for permitted types in wfc.exe.config file.
The default is '-'. Short form is '/ct:'.
- LANGUAGE -
/language:[cs|vb] The language to use for the generated class.
The default is 'CS' (C#). Short form is '/l:'.
/rootnamespace:<string> Specifies the root Namespace for all type declarations.
Valid only for 'VB' (Visual Basic) language.
Short form is '/rns:'.
- MISCELLANEOUS -
/help Display this usage message. Short form is '/?'.
/nologo Suppress compiler copyright message. Short form is '/n'.
/nowarn Ignore compiler warnings. Short form is '/w'.