分类:
2009-10-11 11:14:12
我个人认为ADO2.0在这方面的表现实在是不好,我看ADO更高的版本会不会比较好
一点。或许,要在SQL7.0之下才会有良好的表现,而我使用的是SQL 6.5与Informix。怎
麽说呢?
在SQL Server6.5之下
1.不像RDO2.0 有一个rdConcurLock的设定;虽然ADO有一个adLockPessimistic的
LockType,不过似乎全不是那一回事,怎麽用,都像是乐观的锁定。
2.我设定Connection物件的IsolationLevel,也没有作用
3.RDO 中如果ProgramA 与 ProgramB 同时指到某一笔Record,而後ProgramA成功
的Update该笔资料且Commit,而ProgramB这时也随即Update该笔资料,这时ProgramB
会收到一个错误讯息,这时只要下
Recordset.Move 0
Recordset.Edit
'设定更改的值
Recordset.Update 便可以重新来做一次
但是ADO呢,我个人认为在Update之後产生错误时,正确的使用方式应是:
(rs as ADODB.Recordset)
rs.CancelUpdate
rs.Resync adAffectCurrent
'set new value for recordset
rs.Update
但实际上会在rs.Resync adAffectCurrent这一行再产生错误,而此时Recordset
的内容却有Refresh成Remote数据库的实际资料内容,好奇怪!我不知道这里是我
的做法有误,还是SQL Server 7.0才能如此,至少SQL Server6.5我失败了。以至
於Update的程序要变成:
cn.BeginTrans
On Error Resume Next
rs!fld1 = "v"
rs.Update
Do While cn.Errors.Count > 0
If cn.Errors(cn.Errors.Count - 1).Number = -2147217887 Then
'-2147217887 代表该Record可能被他人更新了 for Server端Cirsor
ans = MsgBox("资料更新有冲突,是否再试一次", vbYesNo)
If ans = vbYes Then
rs.CancelUpdate
rs.Resync adAffectCurrent '这里也会产生一个error
cn.Errors.Clear
rs!fld1 = "v"
rs.Update
Else
Exit Do
End If
Else
Exit Do
End If
Loop
If cn.Errors.Count = 0 Then
cn.CommitTrans
Else
cn.RollbackTrans
End If
以上程序是rs.CursorLocation = adUseServer 的情况,而用rs.CursorLocation =
adUseClient呢,情况又不太相同,基本上这是不提供rs.Resync方法。
在Informix之下(用OpenLink的ODBC Driver)呢,情况很乱,後来我发现只要使用Client
端的Cursor,问题会减到最少,而且这里有一点十分奇特,OpenLink ODBC Driver允许
我们使用Recordset的Resync方法,不但没有错,而且还会把on-line Database的资料
传回来(这一点和使用RDO 的Client端Cursor不同,和 ADO SQL Server6.5也不同)。
所以,以下是我OpenLink ODBC Driver解决Update concurrency的方式。特别提出是,
在这OpenLink ODBC Driver下使用ADO,千万不要用Server端的Cursor,会有太多问题。
以下的程序只可用於OpenLink Informix ODBC Driver,不可用於SQL Server!!