分类:
2009-10-11 11:16:56
来源:cww
在VB所用的MDB数据库来说,锁定可以分成
1.整个数据库的层级
以独占方式开启(OpenDatabase的第二个叁数为true表示Exclusive Mode)
Dim db As Database
Set db = OpenDatabase("f:\vbprg\chart", True) '独占方式Open Database
如果成功了,别人也就没有办法与你共用该Database
2.锁定Table的层级
在OpenRecordset 时设定第三个叁数为dbDenyRead + dbDenyWrite 便可以防上他人
同时开启该Table,而使用这种Table Lock,其第二个叁数只能是dbOpenTable或是
dbOpenDynaset,而dbOpenDynamic、dbOpenSnapshot等则不能使用Table Lock
如下,产生一个独占的rs RecordSet。
Set rs = db.OpenRecordset(TableName, dbOpenTable, dbDenyRead + dbDenyWrite)
3.锁定Page的层级,这又分
a.悲观锁定
'RS 是 RecordSet物件的引用
RS.LockEdit = True
时是悲观的锁定,也就是说,如果RecordSet物件下.Edit方法成功时,便会将该
Record所在的Page加以锁定,一直到.Update/.CancelUpdate 才解锁。底下有一
个Function RecordEdit(recst As Recordset, Optional ntimes) As Boolean
用在悲观的锁定,ntime表示尝试锁定多少次,超过次数後才失败传回False。
b.乐观的锁定
RS.LockEdit = False
当RecordSet物件下.Edit的方法後,并没有Lock该Page,直到下.Update时才Lock
之後立即解锁,这个方式的特性是,在.Edit之後如果同一笔Record已被他人先修
改过,那麽我们下的.Update方法会有错误,此时配合On Error的方式,再下一次
.Update的方法,来更动成我们所要的内容。另外有一个Function
RecordUpdate(recst As Recordset, Optional ntimes) As Boolean
用在乐观的锁定,ntime表示尝试Update多少次,超过次数後才失败传回False。
一个Page内会有一笔以上的Record,所以PageLock时,在同一个Page下的所有Record都
会被Lock住,而Access的数据库没有办法做到Record Lock这和XBase有所不同;那有没
有可能一笔Record超过一个Page,而变成Page Lock时并没有Lock住该笔Record的全部,
我想,这应不可能,因为一笔Record的最大长度有限制,超过时根本没有办法建立该
Table,而Binary/Meno 之类的大量资料,并不是和其他的这些资料放在一起。
'开启一个表格,db:表格所在的Database引用, rs 传回该表格的RecordSet
'TableName表格名称,ExclusiveMode:是否独占开启。
Public Function OpenTable(db As Database, rs As Recordset, ByVal TableName As String, ByVal ExclusiveMode As Boolean) As Boolean
Dim i As Integer
On Error GoTo ErrHandler
OpenTable = True
If ExclusiveMode Then
Set rs = db.OpenRecordset(TableName, dbOpenTable, dbDenyRead + dbDenyWrite)
Else
Set rs = db.OpenRecordset(TableName, dbOpenTable)
End If
Exit Function
ErrHandler:
OpenTable = False
End Function
'用在悲观的锁定,ntime表示尝试锁定多少次,超过次数後才失败传回False
Public Function RecordEdit(recst As Recordset, Optional ntimes) As Boolean
Dim i As Integer
i = 0
If IsMissing(ntimes) Then
ntimes = 5
End If
On Error Resume Next
Do While True
Err.Clear
recst.Edit
If Err.Number <> 0 Then
If ntimes <> 0 Then
If i < ntimes Then
i = i + 1
Else
RecordEdit = False
Exit Do
End If
End If
Else
RecordEdit = True
Exit Do
End If
Loop
End Function
'用在乐观的锁定,ntime表示尝试Update多少次,超过次数後才失败传回False
Public Function RecordUpdate(recst As Recordset, Optional ntimes) As Boolean
Dim i As Integer
i = 0
If IsMissing(ntimes) Then
ntimes = 5
End If
On Error Resume Next
Do While True
Err.Clear
recst.Update
If Err.Number <> 0 Then
If ntimes <> 0 Then
If i < ntimes Then
i = i + 1
Else
RecordUpdate = False
Exit Do
End If
End If
Else
RecordUpdate = True
Exit Do
End If
Loop
End Function
|