[返回]
计算机世界1999年第25期

解决ACCAESS的数据冲突

深圳供电局自动化分部 杨炯夫

  在使用ACCESS 时,经常会有这样的情况:好多个用户同时对某个Table 读取数据,对数据加工处理,然后保存数据。当二个以上用户用同一条记录,同时又对这条记录加工处理时,如果处理不好,就会产生数据丢失。
  如果用ACCESS 的query 去读取数据、更新数据的话,肯定会丢失数据。笔者在实际工作中,用ACCESS 的module 很好地解决了这个问题。

  一、ACCESS 的Table

  下面的Module 是对ACCESS 的table 进行操作。
  调用该Module,如果申请成功,则返回新用户号;如果申请不成功,则返回0。
Function get_local_id()
Dim bms As Database
Dim rst As Recordset
Dim try_count As Integer

Set bms = CurrentDb()

try_count = 1

retry:

Set rst = bms.OpenRecordset
("cust_seed_recs", dbDenyWrite)
' 对Table  cust_seed_recs 进行加锁,
不允许其他用户对该Table 进行写操作
On Error GoTo err_lock

get_local_id = rst!cust_seed_no

rst.Edit
rst!cust_seed_no = rst!cust_seed_no +1
rst.update

ExitLockEdits:
    rst.close
    Set bms = Nothing
    Exit Function

err_lock:
  try_count = try_count +1
  ' 最多试十次
  If try_count > 10 Then
     MsgBox "重试超过十次,
               请稍后再试."
     get_local_id = 0
     Resume ExitLockEdits
  Else
     rst.close
     Resume retry
  End If
  
End Function

  二、远程数据库的Table

  对通过ODBC 链接的远程数据库的Table,用函数OpenRecordset("register_seed", dbDenyWrite) 时,会报“无效操作”的错误信息,也就是说ACCESS 不能对远程数据库的Table 进行加锁。为了解决这个问题,用函数OpenRecordset("register_seed", dbOpenDynaset) 来打开远程数据库的Table "register_seed",对它的字段进行编辑,当最后用Update 提交修改时,如果发生冲突, 则返回错误信息,根据不同的错误信息进行相应的处理;如果不发生冲突,则修改成功。
  下面的Module 是远程数据库的Table 进行操作,它的功能是顺序产生一个全局的登记号给用户。
  调用该Module,如果申请成功,则返回新登记号;如果申请不成功,则返回0。
Public Function get_reg_id()
Dim bms As Database
Dim rst As Recordset
Dim try_count As Integer

Set bms = CurrentDb
    
    try_count = 1

retry:

    Set rst = bms.OpenRecordset
   ("register_seed", dbOpenDynaset)

    rst.LockEdits = True
    On Error GoTo ErrorLockEdits
    
    get_reg_id = rst!register_no
    
    rst.Edit
    rst!register_no = rst!register_no +1
    rst.update

ExitLockEdits:
    rst.close
    Set bms = Nothing
    Exit Function

ErrorLockEdits:
        If Err.Number = 3197 Then
        
If MsgBox("数据已被其他用户修改,
          是否重试?",
      &_  vbOKCancel, "Error!") = vbOK Then
      try_count = try_count +1
      If try_count > 10 Then
        MsgBox "重试超过十次,
                  请稍后再试."
        get_reg_id = 0
        Resume ExitLockEdits
      End If
      rst.close
      Resume retry
      Else
         get_reg_id = 0
         Resume ExitLockEdits
      End If
      Else
         MsgBox "其他错误."
         get_reg_id = 0
         Resume ExitLockEdits
      End If

End Function