.NET 數(shù)據(jù)訪問架構(gòu)向?qū)?/h1>
發(fā)表時(shí)間:2024-02-10 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]使用自動化事務(wù) 自動化事務(wù)簡化了編程模型,因?yàn)樗鼈儾恍枰鞔_地開始新事務(wù)處理過程,或明確執(zhí)行或取消事務(wù)。然而,自動化事務(wù)的最大優(yōu)點(diǎn)是它們能與DTC結(jié)合起來,這就使單個事務(wù)可以擴(kuò)展到多個分布式數(shù)據(jù)源中。在大型分布式應(yīng)用程序中,這個優(yōu)點(diǎn)是很重要的。盡管通過手工對DTC直接編程來控制分布式事務(wù)是可能的...
使用自動化事務(wù)
自動化事務(wù)簡化了編程模型,因?yàn)樗鼈儾恍枰鞔_地開始新事務(wù)處理過程,或明確執(zhí)行或取消事務(wù)。然而,自動化事務(wù)的最大優(yōu)點(diǎn)是它們能與DTC結(jié)合起來,這就使單個事務(wù)可以擴(kuò)展到多個分布式數(shù)據(jù)源中。在大型分布式應(yīng)用程序中,這個優(yōu)點(diǎn)是很重要的。盡管通過手工對DTC直接編程來控制分布式事務(wù)是可能的,但自動化事務(wù)處理極大的簡化了工作量,并且它是為基于組件的系統(tǒng)而設(shè)計(jì)的。例如,可以方便地以說明方式配置多個組件以執(zhí)行包含了單個事務(wù)處理的任務(wù)。
自動化事務(wù)依賴于COM+提供的分布式事務(wù)處理支持特性。結(jié)果,只有服務(wù)組件(即從ServicedComponent類中派生的組件)能夠使用自動化事務(wù)。
要為自動化事務(wù)處理配置類,操作如下:
從位于EnterpriseServices名稱空間的ServicedComponent類中派生新類。
通過Transaction屬性定義類的事務(wù)處理需求。來自TransactionOption的枚舉值決定了如何在COM+類中配置類。可與此屬性一同設(shè)置的其它屬性包括事務(wù)處理分離等級和超時(shí)上限。
為了避免必須明確選出事務(wù)處理結(jié)果,可以用AutoComplete屬性對方法進(jìn)行注釋。如果這些方法釋放異常,事務(wù)將自動取消。注意,如果需要,仍可以直接挑選事務(wù)處理結(jié)果。更多詳情,見本文稍后確定事務(wù)處理結(jié)果的節(jié)。
更多信息
關(guān)于COM+自動化事務(wù)的更多信息,可在平臺SDK文檔中搜索“通過COM+的自動化事務(wù)”獲取。
關(guān)于.NE T事務(wù)處理類的示例,見附錄中的如何編碼.NET事務(wù)處理。
配置事務(wù)處理分離級別
用于COM+1.0版--即運(yùn)行在Windows 2000中的COM+--的事務(wù)處理分離級別被序列化了。這樣做提供了最高的分離等級,卻是以性能為代價(jià)的。系統(tǒng)的整體吞吐量被降低了。因?yàn)樗婕暗降馁Y源管理器(典型地是數(shù)據(jù)庫)在事務(wù)處理期間必須保持讀和寫鎖。在此期間,其它所有事務(wù)處理都被阻斷了,這種情況將對應(yīng)用程序的擴(kuò)展能力產(chǎn)生極大沖擊。
隨微軟Windows .NET發(fā)行的COM+ 1.5版允許有COM+目錄中按組件配置事務(wù)處理分離等級。與事務(wù)中根組件相關(guān)的設(shè)置決定了事務(wù)處理的分離等級。另外,同一事務(wù)流中的內(nèi)部子組件擁有的事務(wù)處理等級必須不能高于要組件所定義的等級。如果不是這樣,當(dāng)子組件實(shí)例化時(shí),將導(dǎo)致錯誤。
對.NET管理類,Transaction屬性支持所有的公有Isolation屬性。你可以用此屬性陳述式地指定一特殊分離等級,如下面的代碼所示:
[Transaction(TransactionOption.Supported, Isolation=TransactionIsolationLevel.ReadCommitted)]
public class Account : ServicedComponent
{
. . .
}
更多信息
關(guān)于配置事務(wù)處理分離等級及其它Windows .NET COM+增強(qiáng)特性的更多信息,見MSDN雜志2001年8月期的“Windows XP:利用COM+ 1.5的增強(qiáng)特性使你的組件更強(qiáng)壯”一文。
確定事務(wù)處理結(jié)果
在單個事務(wù)流的所有事務(wù)處理組件上下文中,自動化事務(wù)處理結(jié)果由事務(wù)取消標(biāo)志和一致性標(biāo)志的狀態(tài)決定。當(dāng)事務(wù)流中的根組件成為非活動狀態(tài)(并且控制權(quán)返回調(diào)用者)時(shí),確定事務(wù)處理結(jié)果。這種情況在圖5中得到了演示,此圖顯示的是一個典型的銀行基金傳送事務(wù)。
圖5 事務(wù)流上下文
當(dāng)根對象(在本例中是對象)變?yōu)榉腔顒訝顟B(tài),并且客戶的方法調(diào)用返回時(shí),確定事務(wù)處理結(jié)果。在任何上下文中的任何一致性標(biāo)志被設(shè)為假,或如果事務(wù)處理取消標(biāo)志設(shè)為真,那么底層的物理DTC事務(wù)將被取消。
可以以下面兩種方式之一從.NET對象中控制事務(wù)處理結(jié)果:
可以用AutoComplete屬性對方法進(jìn)行注釋,并讓.NET自動存放將決定事務(wù)處理結(jié)果投票。如果方法釋放異常,利用此屬性,一致性標(biāo)志自動地被設(shè)為假(此值最終使事務(wù)取消)。如果方法返回而沒有釋放異常,那么一致性標(biāo)志將設(shè)為真,此值指出組件樂于執(zhí)行事務(wù)。這并沒有得到保證,因?yàn)樗蕾囉谕皇聞?wù)流中其它對象的投票。
可以調(diào)用ContextUtil類的靜態(tài)方法SetComplete或 SetAbort,這些方法分別將一致性標(biāo)志設(shè)為真或假。
嚴(yán)重性大于10的SQL Server錯誤將導(dǎo)致管理數(shù)據(jù)供應(yīng)器釋放SqlException類型的異常。如果方法緩存并處理異常,就要確;蛘咄ㄟ^手工取消了事務(wù),或者方法被標(biāo)記了[AutoComplete],以保證異常能傳遞回調(diào)用者。
AutoComplete方法
對于標(biāo)記了屬性的方法,執(zhí)行下面操作:
將SqlException傳遞加調(diào)用堆棧。
將SqlException封裝在外部例外中,并傳遞回調(diào)用者。也可以將異常封裝在對調(diào)用者更有意義的異常類型中。
異常如果不能傳遞,將導(dǎo)致對象不會提出取消事務(wù),從而忽視數(shù)據(jù)庫錯誤。這意味著共享同一事務(wù)流的其它對象的成功操作將被提交。
下面的代碼緩存了SqlException,然后將它直接傳遞回調(diào)用者。事務(wù)處理最終將被取消,因?yàn)閷ο蟮囊恢滦詷?biāo)志在對象變?yōu)榉腔顒訝顟B(tài)時(shí)自動被設(shè)為假。
[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塊內(nèi)調(diào)用ContextUtil.SetAbort以終止事務(wù)處理。這就將相容標(biāo)志設(shè)置為假。
如果沒有發(fā)生異常事件,調(diào)用ContextUtil.SetComplete,以提交事務(wù),這就將相容標(biāo)志設(shè)置為真(缺省狀態(tài))。
代碼說明了這種方法。
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塊,在方法開始的時(shí)候調(diào)用ContextVtil.SetAbort,以及在try塊的末尾調(diào)用ContextUtil.SetComplete都會變得容易。用這種方法,就不需要在每個catch塊中重復(fù)調(diào)用ContextUtil.SetAbort。通過這種方法確定的相容標(biāo)志的設(shè)置只在方法返回時(shí)有效。
對于異常事件(或循環(huán)異常),必須把它傳遞到調(diào)用堆棧中,因?yàn)檫@使得調(diào)用代碼認(rèn)為事務(wù)處理失敗。它允許調(diào)用代碼做出優(yōu)化選擇。比如,在銀行資金轉(zhuǎn)賬中,如果債務(wù)操作失敗,則轉(zhuǎn)帳分支可以決定不執(zhí)行債務(wù)操作。
如果把相容標(biāo)志設(shè)置為假并且在返回時(shí)沒有出現(xiàn)異常事件,則調(diào)用代碼就沒有辦法知道事務(wù)處理是否一定失敗。雖然可以返回Boolean值或設(shè)置Boolean輸出參數(shù),但還是應(yīng)該前后一致,通過顯示異常事件以表明有錯誤發(fā)生。這樣代碼就有一種標(biāo)準(zhǔn)的錯誤處理方法,因此更簡明、更具有相容性。
數(shù)據(jù)分頁
在分布式應(yīng)用程序中利用數(shù)據(jù)進(jìn)行分頁是一項(xiàng)普遍的要求。比如,用戶可能得到書的列表而該列表又不能夠一次完全顯示,用戶就需要在數(shù)據(jù)上執(zhí)行一些熟悉的操作,比如瀏覽下一頁或上一頁的數(shù)據(jù),或者跳到列表的第一頁或最后一頁。
這部分內(nèi)容將討論實(shí)現(xiàn)這種功能的選項(xiàng),以及每種選項(xiàng)在性能和縮放性上的效果。
選項(xiàng)比較
數(shù)據(jù)分頁的選項(xiàng)有:
利用SqlDataAdapter的Fill方法,將來自查詢處的結(jié)果填充到DataSet中。
通過COM的可相互操作性使用ADO,并利用服務(wù)器光標(biāo)。
利用存儲的過程手工實(shí)現(xiàn)數(shù)據(jù)分頁。
對數(shù)據(jù)進(jìn)行分頁的最優(yōu)選項(xiàng)依賴于下列因素:
[1] [2] [3] 下一頁