分类:
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!!