【摘 要】對(duì)于那些僅僅允許用戶查看數(shù)據(jù),或者僅有一個(gè)用戶可以修改數(shù)據(jù)的web應(yīng)用軟件,不存在多用戶并發(fā)沖突的問(wèn)題。然而對(duì)于那些允許多個(gè)用戶修改或刪除數(shù)據(jù)的web應(yīng)用軟件,則有可能發(fā)生一個(gè)用戶所做的更改與另一個(gè)并發(fā)用戶的更改沖突。在沒(méi)有任何并發(fā)策略的地方,當(dāng)兩個(gè)用戶同時(shí)編輯某一條記錄,最后提交的用戶的更改將覆蓋先提交的用戶所作的更改。當(dāng)設(shè)計(jì)這樣的程序時(shí),選擇適當(dāng)?shù)牟l(fā)控制技術(shù)非常重要。本文介紹了三種并發(fā)控制策略:最后更新生效、開(kāi)放式并發(fā)、保守式并發(fā),分析各種控制策略優(yōu)缺點(diǎn),以尋求適合企業(yè)信息化建設(shè)的解決方案。
【關(guān)鍵詞】并發(fā)控制;最后更新生效;開(kāi)放式并發(fā);保守式并發(fā)
1、引言
企業(yè)信息化建設(shè)最主要就是與數(shù)據(jù)庫(kù)打交道,對(duì)數(shù)據(jù)庫(kù)進(jìn)行插、刪、改、查等操作,難免會(huì)發(fā)生一個(gè)用戶所做的更改與另一個(gè)并發(fā)用戶的更改沖突,例如:在沒(méi)有任何并發(fā)策略的地方,當(dāng)兩個(gè)用戶同時(shí)編輯某一條記錄,最后提交的用戶的更改將覆蓋先提交的用戶所作的更改;當(dāng)兩個(gè)用戶同時(shí)訪問(wèn)一個(gè)頁(yè)面,一個(gè)用戶可能更新的事另一個(gè)用戶已經(jīng)刪除的記錄;在一個(gè)用戶加載頁(yè)面跟他點(diǎn)擊刪除按鈕之間的時(shí)間里,另一個(gè)用戶修改了這條記錄的內(nèi)容等,當(dāng)設(shè)計(jì)這樣的程序時(shí),選擇適當(dāng)?shù)牟l(fā)控制技術(shù)非常重要。
本文介紹了三種并發(fā)控制策略:最后更新生效、開(kāi)放式并發(fā)、保守式并發(fā),分析各種控制策略優(yōu)缺點(diǎn),以尋求并詳細(xì)介紹適合企業(yè)開(kāi)發(fā)信息化建設(shè)的解決方案。
2、并發(fā)控制策略
2.1 最后更新生效
最后更新生效是開(kāi)發(fā)默認(rèn)行為,即如果并發(fā)用戶修改的是同一條記錄,讓最后提交的結(jié)果生效。最后更新生效雖然在開(kāi)發(fā)時(shí)不用進(jìn)行并發(fā)控制策略的設(shè)置,但在運(yùn)行時(shí),會(huì)使用戶混淆數(shù)據(jù)。此種方式適合單位范圍內(nèi)用戶與角色一一對(duì)應(yīng)的系統(tǒng),例如方案設(shè)計(jì)、設(shè)備參數(shù)采集、生產(chǎn)數(shù)據(jù)采集等。
2.2 開(kāi)放式并發(fā)
開(kāi)放式并發(fā),數(shù)據(jù)在更新之前都是可以被其他用戶使用的,只有在更新的時(shí)候,才鎖定記錄。更新的時(shí)候,對(duì)比與查詢之初的數(shù)據(jù)是否吻合,如果不一致,則不運(yùn)行修改。此種控制方式也可以完全保證數(shù)據(jù)的完整性,其優(yōu)點(diǎn)是不會(huì)占用其他用戶訪問(wèn)該數(shù)據(jù)的權(quán)限,缺點(diǎn)是由于其他用戶可能已經(jīng)更新了這些數(shù)據(jù),導(dǎo)致本次更新可能不會(huì)完成。開(kāi)放式并發(fā)多以開(kāi)發(fā)人員通過(guò)程序本身的業(yè)務(wù)邏輯來(lái)實(shí)現(xiàn)。
2.3 保守式并發(fā)
保守式并發(fā),數(shù)據(jù)從數(shù)據(jù)庫(kù)取出之后,一直處于鎖定的狀態(tài),其他用戶不能獲取該數(shù)據(jù),直至數(shù)據(jù)更新完畢,用戶才能取出該數(shù)據(jù)進(jìn)行操作。此控制方式對(duì)于性能和資源占用得很多,由于只能同時(shí)有一個(gè)用戶對(duì)數(shù)據(jù)享用操作權(quán),所以可能會(huì)在正常業(yè)務(wù)中,影響其他用戶的處理進(jìn)程。但此控制方式可以完全保證數(shù)據(jù)的完整性。該方式可以通過(guò).NET提供的事務(wù)機(jī)制來(lái)實(shí)現(xiàn),前提是數(shù)據(jù)源需要支持事務(wù)。保守式并發(fā)主要用于對(duì)數(shù)據(jù)存在激烈爭(zhēng)用,或用鎖保護(hù)數(shù)據(jù)的成本小于在發(fā)生并發(fā)沖突時(shí)回滾事務(wù)的成本,例如訂票網(wǎng)站。
3、企業(yè)開(kāi)發(fā)信息化建設(shè)中并發(fā)控制策略選擇及實(shí)現(xiàn)
開(kāi)放式并發(fā)不需要鎖定任何記錄,會(huì)提高性能,因?yàn)殒i定記錄需要附加的服務(wù)器資源,也不會(huì)為了維護(hù)記錄鎖而與數(shù)據(jù)庫(kù)服務(wù)器保持持久連接,所以可以在較少的時(shí)間內(nèi)為大量的客戶端提供服務(wù)。因此在企業(yè)開(kāi)發(fā)信息化建設(shè)中多采用開(kāi)放式并發(fā)來(lái)實(shí)現(xiàn)并發(fā)控制。
目前,企業(yè)信息化建設(shè)中用戶的權(quán)限是通過(guò)角色來(lái)控制的,單位范圍內(nèi)用戶的角色與崗位是一一對(duì)應(yīng)的,所以,一般情況下不需要采用并發(fā)控制,就可以保證數(shù)據(jù)完整性。但是,也會(huì)存在特殊情況,例如,用戶在采集數(shù)據(jù)后,審核人員的審核和采集人員的修改就會(huì)產(chǎn)生并發(fā)情況,這時(shí)候就需要采取措施來(lái)控制,一種是通過(guò)業(yè)務(wù)邏輯來(lái)實(shí)現(xiàn),例如在數(shù)據(jù)采集后,如果不提交數(shù)據(jù),審核人員不能進(jìn)行審核,這時(shí)采集人員可以進(jìn)行修改、刪除等操作,只有在提交后,審核人員才可以進(jìn)行審核,這時(shí)采集人員就不可以進(jìn)行其它操作了;另一種是通過(guò)開(kāi)發(fā)工具來(lái)輔助實(shí)現(xiàn)并發(fā)控制的。
下面通過(guò).NET的數(shù)據(jù)庫(kù)控件為例,介紹開(kāi)放式并發(fā)策略的實(shí)現(xiàn)。在開(kāi)放式并發(fā)模型中,如果當(dāng)某用戶接收到來(lái)自數(shù)據(jù)庫(kù)的值后,另一用戶在該用戶試圖修改該值之前即將其修改,則認(rèn)為發(fā)生了沖突。
3.1 創(chuàng)建一個(gè)支持開(kāi)放式并發(fā)的數(shù)據(jù)訪問(wèn)層
與數(shù)據(jù)打交道時(shí),把數(shù)據(jù)訪問(wèn)邏輯從表現(xiàn)層分離開(kāi)來(lái)。這個(gè)分開(kāi)的層被稱作是數(shù)據(jù)訪問(wèn)層,簡(jiǎn)寫(xiě)為DAL,一般是通過(guò)一個(gè)單獨(dú)的類庫(kù)項(xiàng)目來(lái)實(shí)現(xiàn)的。
3.2 創(chuàng)建一個(gè)支持啟用了開(kāi)放式并發(fā)的DAL的業(yè)務(wù)邏輯層
業(yè)務(wù)邏輯層(BLL)是在數(shù)據(jù)訪問(wèn)層和表現(xiàn)層之間進(jìn)行數(shù)據(jù)交換的橋梁,在一個(gè)實(shí)際的應(yīng)用程序中,BLL都是以類庫(kù)的形式來(lái)實(shí)現(xiàn)的,每一個(gè)BLL類都對(duì)應(yīng)DAL中的一個(gè)TableAdapter,它們都從各自的TableAdapter中得到讀取、插入、修改以及刪除等方法以應(yīng)用合適的業(yè)務(wù)規(guī)則。然后,通過(guò)BLL類訪問(wèn)類型化數(shù)據(jù)集,給DataRow添加字段級(jí)驗(yàn)證,并給BLL類添加業(yè)務(wù)規(guī)則。
3.3 從ASP.NET頁(yè)面把原始值和新值傳入BLL 方法
完成了DAL和BLL后,剩下的工作就是創(chuàng)建一個(gè)能利用系統(tǒng)中內(nèi)建的開(kāi)放式并發(fā)邏輯的ASP.NET頁(yè)面,這部分屬于表現(xiàn)層,用戶就是通過(guò)這個(gè)層與數(shù)據(jù)庫(kù)打交道的。數(shù)據(jù)Web服務(wù)器控件必須記住它的原始值,并且ObjectDataSource必須同時(shí)傳送這兩套值到業(yè)務(wù)邏輯層。此外,ASP.NET頁(yè)面必須加以配置從而適當(dāng)?shù)靥幚聿l(fā)沖突。
3.4 測(cè)試并添加提示信息并且在發(fā)生并發(fā)沖突時(shí)顯示
驗(yàn)證并發(fā)沖突是否能夠被發(fā)現(xiàn),我們需要打開(kāi)兩個(gè)瀏覽器窗口來(lái)訪問(wèn)這個(gè)頁(yè)面,并在頁(yè)面上進(jìn)行更改操作,當(dāng)點(diǎn)擊第二個(gè)窗口中的更新按鈕時(shí)導(dǎo)致了一個(gè)DBConcurrencyException異常,說(shuō)明現(xiàn)在有了開(kāi)發(fā)式并發(fā)設(shè)置。當(dāng)一個(gè)并發(fā)沖突出現(xiàn)時(shí),可以用Label控件來(lái)捕獲異常信息。
4、結(jié)束語(yǔ)
并發(fā)沖突可能存在于所有允許多用戶同時(shí)更新或刪除數(shù)據(jù)的應(yīng)用程序里。在企業(yè)開(kāi)發(fā)信息化建設(shè)中,如果極少面對(duì)多個(gè)用戶同時(shí)更新數(shù)據(jù),或者不同的用戶對(duì)數(shù)據(jù)作出不同的更改,那么并發(fā)控制并非必選項(xiàng)。然而,如果時(shí)常面對(duì)多個(gè)用戶在線并且對(duì)同一些數(shù)據(jù)進(jìn)行操作,并發(fā)控制可以幫助預(yù)防一個(gè)用戶的更新或刪除被另一個(gè)用戶在不知情的情況下覆蓋。
.NET中的類型化數(shù)據(jù)集提供了支持開(kāi)放式并發(fā)控制的功能。特別地,發(fā)送到數(shù)據(jù)庫(kù)的UPDATE和DELETE語(yǔ)句包含了這個(gè)表的所有字段,從而確保了僅當(dāng)該記錄目前的值與用戶開(kāi)始他們的修改或更新時(shí)的原始值相匹配時(shí),修改或刪除才會(huì)發(fā)生。
參考文獻(xiàn)
[1] Scott Mitchell,在ASP.NET 2.0中操作數(shù)據(jù):實(shí)現(xiàn)開(kāi)放式并發(fā)