使用自動化事務 自動化事務簡化了編程模型,因為它們不需要明確地開始新事務處理過程,或明確執行或取消事務。然而,自動化事務的最大優點是它們能與DTC結合起來,這就使單個事務可以擴展到多個分布式數據源中。在大型分布式應用程序中,這個優點是很重要的。盡管通過手工對DTC直接編程來控制分布式事務是可能的,但自動化事務處理極大的簡化了工作量,并且它是為基于組件的系統而設計的。例如,可以方便地以說明方式配置多個組件以執行包含了單個事務處理的任務。 自動化事務依賴于COM+提供的分布式事務處理支持特性。結果,只有服務組件(即從ServicedComponent類中派生的組件)能夠使用自動化事務。 要為自動化事務處理配置類,操作如下: 從位于EnterpriseServices名稱空間的ServicedComponent類中派生新類。 通過Transaction屬性定義類的事務處理需求。來自TransactionOption的枚舉值決定了如何在COM+類中配置類。可與此屬性一同設置的其它屬性包括事務處理分離等級和超時上限。 為了避免必須明確選出事務處理結果,可以用AutoComplete屬性對方法進行注釋。如果這些方法釋放異常,事務將自動取消。注意,如果需要,仍可以直接挑選事務處理結果。更多詳情,見本文稍后確定事務處理結果的節。 更多信息 關于COM+自動化事務的更多信息,可在平臺SDK文檔中搜索“通過COM+的自動化事務”獲取。 關于.NE T事務處理類的示例,見附錄中的如何編碼.NET事務處理。 配置事務處理分離級別 用于COM+1.0版--即運行在Windows 2000中的COM+--的事務處理分離級別被序列化了。這樣做提供了最高的分離等級,卻是以性能為代價的。系統的整體吞吐量被降低了。因為所涉及到的資源管理器(典型地是數據庫)在事務處理期間必須保持讀和寫鎖。在此期間,其它所有事務處理都被阻斷了,這種情況將對應用程序的擴展能力產生極大沖擊。 隨微軟Windows .NET發行的COM+ 1.5版允許有COM+目錄中按組件配置事務處理分離等級。與事務中根組件相關的設置決定了事務處理的分離等級。另外,同一事務流中的內部子組件擁有的事務處理等級必須不能高于要組件所定義的等級。如果不是這樣,當子組件實例化時,將導致錯誤。 對.NET管理類,Transaction屬性支持所有的公有Isolation屬性。你可以用此屬性陳述式地指定一特殊分離等級,如下面的代碼所示: [Transaction(TransactionOption.Supported, Isolation=TransactionIsolationLevel.ReadCommitted)] public class Account : ServicedComponent { . . . } 更多信息 關于配置事務處理分離等級及其它Windows .NET COM+增強特性的更多信息,見MSDN雜志2001年8月期的“Windows XP:利用COM+ 1.5的增強特性使你的組件更強壯”一文。 確定事務處理結果 在單個事務流的所有事務處理組件上下文中,自動化事務處理結果由事務取消標志和一致性標志的狀態決定。當事務流中的根組件成為非活動狀態(并且控制權返回調用者)時,確定事務處理結果。這種情況在圖5中得到了演示,此圖顯示的是一個典型的銀行基金傳送事務。
圖5 事務流上下文 當根對象(在本例中是對象)變為非活動狀態,并且客戶的方法調用返回時,確定事務處理結果。在任何上下文中的任何一致性標志被設為假,或如果事務處理取消標志設為真,那么底層的物理DTC事務將被取消。 可以以下面兩種方式之一從.NET對象中控制事務處理結果: 可以用AutoComplete屬性對方法進行注釋,并讓.NET自動存放將決定事務處理結果投票。如果方法釋放異常,利用此屬性,一致性標志自動地被設為假(此值最終使事務取消)。如果方法返回而沒有釋放異常,那么一致性標志將設為真,此值指出組件樂于執行事務。這并沒有得到保證,因為它依賴于同一事務流中其它對象的投票。 可以調用ContextUtil類的靜態方法SetComplete或 SetAbort,這些方法分別將一致性標志設為真或假。 嚴重性大于10的SQL Server錯誤將導致管理數據供應器釋放SqlException類型的異常。如果方法緩存并處理異常,就要確保或者通過手工取消了事務,或者方法被標記了[AutoComplete],以保證異常能傳遞回調用者。 AutoComplete方法 對于標記了屬性的方法,執行下面操作: 將SqlException傳遞加調用堆棧。 將SqlException封裝在外部例外中,并傳遞回調用者。也可以將異常封裝在對調用者更有意義的異常類型中。 異常如果不能傳遞,將導致對象不會提出取消事務,從而忽視數據庫錯誤。這意味著共享同一事務流的其它對象的成功操作將被提交。 下面的代碼緩存了SqlException,然后將它直接傳遞回調用者。事務處理最終將被取消,因為對象的一致性標志在對象變為非活動狀態時自動被設為假。 [AutoComplete] void SomeMethod() { try { // Open the connection, and perform database operation . . . } catch (SqlException sqlex ) { LogException( sqlex ); // Log the exception details throw; // Rethrow the exception, causing the consistent // flag to be set to false. } finally { // Close the database connection . . . } } Non-AutoComlete方法 對于沒有AutoComplete的屬性的方法,必須: 在catch塊內調用ContextUtil.SetAbort以終止事務處理。這就將相容標志設置為假。 如果沒有發生異常事件,調用ContextUtil.SetComplete,以提交事務,這就將相容標志設置為真(缺省狀態)。 代碼說明了這種方法。 void SomeOtherMethod() { try { // Open the connection, and perform database operation . . . ContextUtil.SetComplete(); // Manually vote to commit the transaction } catch (SqlException sqlex) { LogException( sqlex ); // Log the exception details ContextUtil.SetAbort(); // Manually vote to abort the transaction // Exception is handled at this point and is not propagated to the caller } finally { // Close the database connection . . . } } 注意 如果有多個catch塊,在方法開始的時候調用ContextVtil.SetAbort,以及在try塊的末尾調用ContextUtil.SetComplete都會變得容易。用這種方法,就不需要在每個catch塊中重復調用ContextUtil.SetAbort。通過這種方法確定的相容標志的設置只在方法返回時有效。 對于異常事件(或循環異常),必須把它傳遞到調用堆棧中,因為這使得調用代碼認為事務處理失敗。它允許調用代碼做出優化選擇。比如,在銀行資金轉賬中,如果債務操作失敗,則轉帳分支可以決定不執行債務操作。 如果把相容標志設置為假并且在返回時沒有出現異常事件,則調用代碼就沒有辦法知道事務處理是否一定失敗。雖然可以返回Boolean值或設置Boolean輸出參數,但還是應該前后一致,通過顯示異常事件以表明有錯誤發生。這樣代碼就有一種標準的錯誤處理方法,因此更簡明、更具有相容性。 數據分頁 在分布式應用程序中利用數據進行分頁是一項普遍的要求。比如,用戶可能得到書的列表而該列表又不能夠一次完全顯示,用戶就需要在數據上執行一些熟悉的操作,比如瀏覽下一頁或上一頁的數據,或者跳到列表的第一頁或最后一頁。 這部分內容將討論實現這種功能的選項,以及每種選項在性能和縮放性上的效果。 選項比較 數據分頁的選項有: 利用SqlDataAdapter的Fill方法,將來自查詢處的結果填充到DataSet中。 通過COM的可相互操作性使用ADO,并利用服務器光標。 利用存儲的過程手工實現數據分頁。 對數據進行分頁的最優選項依賴于下列因素:
[1] [2] [3] 下一頁
|