top
Loading...
多客戶環境下VB數據庫編程之(7)

頁面鎖定的鎖定方案

如前所述,Microsoft Jet不能鎖定單個的記錄,每次讀、寫以及鎖定的都是一頁數據,面不是一個記錄。根據記錄的大小,一頁可能包含多個記錄。當鎖定一個記錄時,就會鎖定那一頁上的所有記錄。

在高并發應用程序中,要求對指定記錄提供暢通無阻的訪問。可以用不同的策略來實現設計。

1.使用Text類型。可以用Text數據類型把字段添加到表中,直到記錄長度超過1024個字節。由于Text是變長數據類型,必須顯式地用數據來填補字段以獲得一個定長格式。同時,這種技術可能會降低性能,因為如果每個記錄都占用2K磁盤空間,則數據庫的長度將會增加。因此,建議不要使用Text 數據類型。

2. 使用CHAR類型。SQL DDL CHAR 是一種定長數據類型。如果使用這種類型,則可不必用數據來填補字段。使用CHAR數據類型是實現這種技術的最簡單而且保險的唯一方法。

3.使用開放鎖定。另一種策略是:在任何地方都使用開放方式鎖定。雖然開放式鎖定不能避免頁面鎖定,但它可以使記錄被鎖定的時間最短,因此降低了不需要鎖定的記錄也被鎖定的可能性。

4.使用自定義的鎖定方案。有時候,頁面鎖定不能滿足需要,而開放式鎖定也可能無法滿足需要。在這種情況下,可以考慮使用自定義的鎖定方案。當一個記錄被鎖定時,可以用一個鎖定表來標識。鎖定表存儲記錄的鍵值、鎖定狀態(鎖定或未鎖定)以及鎖定記錄的用戶名等。自定義鎖定方案的實現需要大量的設計、實現以及測試時間。在許多情況下,它不能與內置的Microsoft Jet的功能重復。例如,即使實現單記錄鎖定,處理基于多個表的記錄集的數據也是非常困難的,因為必須標識所有表,而這些表都包含必須鎖定的記錄。當自定義鎖定方案只影響幾個表,而且不是基于一個具有復雜連結和關系的數據模型時,使用自定義鎖定方案較為適宜。

頁面鎖定中的錯誤處理

當使用頁面鎖定時,必須在代碼中檢查是否成功地實現了鎖定。在開始時應禁止錯誤處理程序,然后嘗試完成初始化一個鎖定、檢查錯誤,最后允許錯誤處理程序。在多用戶環境下,所遇到的頁面鎖定錯誤有三種,見表。

錯誤代碼和出錯信息 原因和建議的操作

3186 不能存儲;當前正被機器上的用戶鎖定 當一個用戶試圖更新一頁,而這一頁包含了另一個用戶設置的讀鎖定時,就會發生這個錯誤。為了處理這個錯誤,可以先等待一會兒,然后重新存儲該記錄。也可以通知發生這個問題的用戶,并詢問他們是否想要重試該操作

3197因為和另一個用戶試圖同時改變同一個數據,所以MicrosoftJet數據庫引擎終止了該過程 在打開記錄集或最后一次從記錄中讀取數據之后,另一個用戶對當前記錄作了更改,并使用Edit方法或Update方法時,就會產生這個錯誤。如果在使用Edit方法時產生了這個錯誤,就要用當前數據來刷新用戶的數據視圖然后再試一次Edit方法。如果這個錯誤是在使用update方法時發生的,則是因為使用了開放式鎖定,并且在使用Edit方法后記錄發生了變更。在這種情況下,應通知用戶,其他人已經改變了數據。可以顯示出當前數據并讓用戶選擇:是覆蓋其他用戶的變更,還是取消編輯

3260不能更新;當前,被機器 上的 用戶鎖定 鎖定了包含當前記錄的頁面,并使用AddNew或Edlt方法時,就會發生這個錯誤。在使用Update方法來把一個記錄存儲到一個鎖定的頁面時,也會發生這個錯誤。在用戶存儲新的記錄,或者在使用了開放式鎖定后,另一個用戶又來鎖定該頁面時,就會發生這種情況。為了處理這個錯誤,可等待一會兒,然后再試一次存儲該記錄。可以將該問題通知用戶,并讓用戶決定是否要重試這個操作

用錯誤代碼和出錯信息可以測試記錄是否被鎖定。下面的過程可用來檢測當前記錄是否在一個鎖定的頁面上:

Function RecordLocked(rst As Recordset)AsBoolean

Dim blnLock As Boolean

On Error GoToErrorHandler

blnLock=rst.LockEdits '保存LockEdits屬性的當前值

rst.LockEdits=True '設置保守式鎖定

rst.Edit '試著編輯記錄,如果記錄被鎖定,則會產生錯誤3197

RecordLocked=False

rst.CancelUpdate

rst.LockEdits=blnLock '恢復LockEdits屬性的值

EXit FUnction

ErrorHandler:

Select Case Err

Case 3197:

Resume Next

Case Else

RecordLocked=True

Resume Next

EXit Function

End Select

End Function

該過程把記錄集的鎖定設置為保守式,并編輯記錄,以測試當前記錄是否在一個被鎖定的頁面上,如果記錄被鎖定,則會產生一個錯誤(3197)。該過程有一個參數,即rst,它是Recordset對象。調用該過程,將返回一個布爾值。為了調用該過程,可以在窗體上畫一個命令按鈕,然后編寫如下事件過程:

Private Sub Command1_Click()

Dim dbs As Database

Dim tb As Recordset

Dim bl As Boolean

Set dbs=opendatabase("c:dbdirdbl.mdb",dbopenDynaset)

Settb=dbs.OpenRecordset("tablel",dbOpenTable)

bl=RecordLocked(tb)

End Sub

在該事件過程中,打開一個數據庫和該數據庫中的表,然后用記錄集作為參數調用上述過程,調用結果放在變量bl中。如果記錄被鎖定,則返回值為True,否則為False。
作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗