程序的数据库是ACCESS。程序在局域网中被共享着。
当1-3人同时打开程序且同时一一在『浏览、或者修改、又或者删除』同一条数据时。
“俺的意思是当小A、小B这两个人同时在浏览编号为“1”的数据。
这时刚好小B删除了编号为“1”的数据,而小A则数据了窗体上的数据后想保存,但出错了 )
请教下“Tiger_Zhao”兄台!当这样的多用户操作同一条记录时所遇到的错误,我们该如何去解决呢?
再次谢谢“Tiger_Zhao”兄台!
4 个解决方案
#1
'刚忘记发下修改后保存的代码了
'这是修改的代码
SQL = "select 序号,类别,名称,单位 from 资料表 where 序号=" & SID
rs.Open SQL, cn, 3, 3
rs!类别 = Me.Text1.Text
rs!名称 = Me.Text2.Text
rs!单位 = Me.Text3.Text
rs.Update
#2
编辑数据之前最好先查询数据是否存在再进行编辑或查看。
对于多人修改同一条数据记录,可以这样考虑:
第一种方法:
谁先编辑那条数据库记录就谁对那条数据记录进行锁定,别人不能操作。
当别人打开改纪录时会出错,可以通过 On Error Resume Next 来捕获错误。
第二种方法:
在数据记录中加三个字段,1个是状态,1个是用户编号,还有一个是操作时间
状态可为数字,0表示没有人操作,1表示有人正在编辑不允许查看,2表示有人正在编辑允许查看。
1、如果状态为0,那么任何人都可以编辑该纪录信息,第一个编辑该纪录信息的人需要向字段的:状态、用户编号、操作时间
写入信息,以便其他用户编辑或查看时提供相关操作信息,而且每隔20秒更新一次时间纪录,防止意外退出造成数据记录被
锁死的情况。
2、如果状态为1,那么其他用户可以判断操作时间的纪录值,如果当前时间-操作时间大于20秒,表示原来操作该纪录的用户
程序可能意外退出没有更新状态信息,这时这个用户可以将自己设为主要操作人,更新状态、用户编号、操作时间等信息。
如果当前时间-操作时间小于等于20秒,那么可以提示要编辑纪录的用户,谁(用户编号)正在编辑该信息,只允许查看该
数据记录内容,然后询问用户是否查看或直接以查看方式打开数据记录。
3、如果状态为2,大致同2的处理,只是最后提示时提示谁(用户编号)正在编辑该信息,不允许用户查看。
对于删除同一条数据记录:
最好使用 Conn.Execute "Delete From 表 Where ID=" & 字段ID
这样删除不会有错误提示,即使条件不符也不会出错。
对于多人修改同一条数据记录,可以这样考虑:
第一种方法:
谁先编辑那条数据库记录就谁对那条数据记录进行锁定,别人不能操作。
当别人打开改纪录时会出错,可以通过 On Error Resume Next 来捕获错误。
第二种方法:
在数据记录中加三个字段,1个是状态,1个是用户编号,还有一个是操作时间
状态可为数字,0表示没有人操作,1表示有人正在编辑不允许查看,2表示有人正在编辑允许查看。
1、如果状态为0,那么任何人都可以编辑该纪录信息,第一个编辑该纪录信息的人需要向字段的:状态、用户编号、操作时间
写入信息,以便其他用户编辑或查看时提供相关操作信息,而且每隔20秒更新一次时间纪录,防止意外退出造成数据记录被
锁死的情况。
2、如果状态为1,那么其他用户可以判断操作时间的纪录值,如果当前时间-操作时间大于20秒,表示原来操作该纪录的用户
程序可能意外退出没有更新状态信息,这时这个用户可以将自己设为主要操作人,更新状态、用户编号、操作时间等信息。
如果当前时间-操作时间小于等于20秒,那么可以提示要编辑纪录的用户,谁(用户编号)正在编辑该信息,只允许查看该
数据记录内容,然后询问用户是否查看或直接以查看方式打开数据记录。
3、如果状态为2,大致同2的处理,只是最后提示时提示谁(用户编号)正在编辑该信息,不允许用户查看。
对于删除同一条数据记录:
最好使用 Conn.Execute "Delete From 表 Where ID=" & 字段ID
这样删除不会有错误提示,即使条件不符也不会出错。
#3
首先要确定业务规则——假定是按照覆盖模式来做,那么效果就是
1)B 先删除,A 再更新,结果就是 A 的数据。
2)A 先保存,B 再删除,结果被删除。
3)B 先更新,A 再更新,结果就是 A 的数据。
4)B 先插入,A 在插入,结果就是 A 的数据。
其次,多用户环境下要用 Connection.Execute 来进行数据操作,RecordSet 在 Open 和 Update 之间可能数据库会被他人改变,处理更复杂。
1)B 先删除,A 再更新,结果就是 A 的数据。
2)A 先保存,B 再删除,结果被删除。
3)B 先更新,A 再更新,结果就是 A 的数据。
4)B 先插入,A 在插入,结果就是 A 的数据。
其次,多用户环境下要用 Connection.Execute 来进行数据操作,RecordSet 在 Open 和 Update 之间可能数据库会被他人改变,处理更复杂。
Private cn As Connection
Private Sub cmdDelete_Click() '删除
Dim SQL As String
SQL = "DELETE FROM 资料表 WHERE 序号=" & SID
cn.Execute SQL '无论记录是否存在,都不会出错
End Sub
Private Sub Form_Load() '新增/更新
Dim SQL As String, lRows As Long
Dim bAddNew As Boolean
On Error GoTo E
bAddNew = '如果可区分新增/更新,分别设置 True/False
'否则始终用 True —— 会降低效率
ReTry:
If bAddNew Then
SQL = "INSERT INTO 资料表 (序号,类别,名称,单位)" & _
" VALUES (" & SID & _
", '" & Text1.Text & "'" & _
", '" & Text2.Text & "'" & _
", '" & Text3.Text & "')"
On Error Resume Next
cn.Execute SQL, lRows, adCmdText 'lRows 返回插入的行数
If Err.Number <> 记录已删除的错误号 Then
MsgBox Err.Description, vbCritical
Exit Sub
End If
On Error GoTo E
End If
If lRows = 0 Then '没做插入或插入不成功(记录已存在)
SQL = "UPDATE 资料表" & _
" SET 类别='" & Text1.Text & "'" & _
", 名称='" & Text2.Text & "'" & _
", 单位='" & Text3.Text & "'" & _
" WHERE 序号=" & SID
cn.Execute SQL, lRows, adCmdText 'lRows 返回更新的行数
If lRows = 0 Then '记录已删除
bAddNew = True
GoTo ReTry
End If
End If
Exit Sub
E:
MsgBox Err.Description, vbCritical
End Sub
#4
谢谢“Tiger_Zhao”兄台
#1
'刚忘记发下修改后保存的代码了
'这是修改的代码
SQL = "select 序号,类别,名称,单位 from 资料表 where 序号=" & SID
rs.Open SQL, cn, 3, 3
rs!类别 = Me.Text1.Text
rs!名称 = Me.Text2.Text
rs!单位 = Me.Text3.Text
rs.Update
#2
编辑数据之前最好先查询数据是否存在再进行编辑或查看。
对于多人修改同一条数据记录,可以这样考虑:
第一种方法:
谁先编辑那条数据库记录就谁对那条数据记录进行锁定,别人不能操作。
当别人打开改纪录时会出错,可以通过 On Error Resume Next 来捕获错误。
第二种方法:
在数据记录中加三个字段,1个是状态,1个是用户编号,还有一个是操作时间
状态可为数字,0表示没有人操作,1表示有人正在编辑不允许查看,2表示有人正在编辑允许查看。
1、如果状态为0,那么任何人都可以编辑该纪录信息,第一个编辑该纪录信息的人需要向字段的:状态、用户编号、操作时间
写入信息,以便其他用户编辑或查看时提供相关操作信息,而且每隔20秒更新一次时间纪录,防止意外退出造成数据记录被
锁死的情况。
2、如果状态为1,那么其他用户可以判断操作时间的纪录值,如果当前时间-操作时间大于20秒,表示原来操作该纪录的用户
程序可能意外退出没有更新状态信息,这时这个用户可以将自己设为主要操作人,更新状态、用户编号、操作时间等信息。
如果当前时间-操作时间小于等于20秒,那么可以提示要编辑纪录的用户,谁(用户编号)正在编辑该信息,只允许查看该
数据记录内容,然后询问用户是否查看或直接以查看方式打开数据记录。
3、如果状态为2,大致同2的处理,只是最后提示时提示谁(用户编号)正在编辑该信息,不允许用户查看。
对于删除同一条数据记录:
最好使用 Conn.Execute "Delete From 表 Where ID=" & 字段ID
这样删除不会有错误提示,即使条件不符也不会出错。
对于多人修改同一条数据记录,可以这样考虑:
第一种方法:
谁先编辑那条数据库记录就谁对那条数据记录进行锁定,别人不能操作。
当别人打开改纪录时会出错,可以通过 On Error Resume Next 来捕获错误。
第二种方法:
在数据记录中加三个字段,1个是状态,1个是用户编号,还有一个是操作时间
状态可为数字,0表示没有人操作,1表示有人正在编辑不允许查看,2表示有人正在编辑允许查看。
1、如果状态为0,那么任何人都可以编辑该纪录信息,第一个编辑该纪录信息的人需要向字段的:状态、用户编号、操作时间
写入信息,以便其他用户编辑或查看时提供相关操作信息,而且每隔20秒更新一次时间纪录,防止意外退出造成数据记录被
锁死的情况。
2、如果状态为1,那么其他用户可以判断操作时间的纪录值,如果当前时间-操作时间大于20秒,表示原来操作该纪录的用户
程序可能意外退出没有更新状态信息,这时这个用户可以将自己设为主要操作人,更新状态、用户编号、操作时间等信息。
如果当前时间-操作时间小于等于20秒,那么可以提示要编辑纪录的用户,谁(用户编号)正在编辑该信息,只允许查看该
数据记录内容,然后询问用户是否查看或直接以查看方式打开数据记录。
3、如果状态为2,大致同2的处理,只是最后提示时提示谁(用户编号)正在编辑该信息,不允许用户查看。
对于删除同一条数据记录:
最好使用 Conn.Execute "Delete From 表 Where ID=" & 字段ID
这样删除不会有错误提示,即使条件不符也不会出错。
#3
首先要确定业务规则——假定是按照覆盖模式来做,那么效果就是
1)B 先删除,A 再更新,结果就是 A 的数据。
2)A 先保存,B 再删除,结果被删除。
3)B 先更新,A 再更新,结果就是 A 的数据。
4)B 先插入,A 在插入,结果就是 A 的数据。
其次,多用户环境下要用 Connection.Execute 来进行数据操作,RecordSet 在 Open 和 Update 之间可能数据库会被他人改变,处理更复杂。
1)B 先删除,A 再更新,结果就是 A 的数据。
2)A 先保存,B 再删除,结果被删除。
3)B 先更新,A 再更新,结果就是 A 的数据。
4)B 先插入,A 在插入,结果就是 A 的数据。
其次,多用户环境下要用 Connection.Execute 来进行数据操作,RecordSet 在 Open 和 Update 之间可能数据库会被他人改变,处理更复杂。
Private cn As Connection
Private Sub cmdDelete_Click() '删除
Dim SQL As String
SQL = "DELETE FROM 资料表 WHERE 序号=" & SID
cn.Execute SQL '无论记录是否存在,都不会出错
End Sub
Private Sub Form_Load() '新增/更新
Dim SQL As String, lRows As Long
Dim bAddNew As Boolean
On Error GoTo E
bAddNew = '如果可区分新增/更新,分别设置 True/False
'否则始终用 True —— 会降低效率
ReTry:
If bAddNew Then
SQL = "INSERT INTO 资料表 (序号,类别,名称,单位)" & _
" VALUES (" & SID & _
", '" & Text1.Text & "'" & _
", '" & Text2.Text & "'" & _
", '" & Text3.Text & "')"
On Error Resume Next
cn.Execute SQL, lRows, adCmdText 'lRows 返回插入的行数
If Err.Number <> 记录已删除的错误号 Then
MsgBox Err.Description, vbCritical
Exit Sub
End If
On Error GoTo E
End If
If lRows = 0 Then '没做插入或插入不成功(记录已存在)
SQL = "UPDATE 资料表" & _
" SET 类别='" & Text1.Text & "'" & _
", 名称='" & Text2.Text & "'" & _
", 单位='" & Text3.Text & "'" & _
" WHERE 序号=" & SID
cn.Execute SQL, lRows, adCmdText 'lRows 返回更新的行数
If lRows = 0 Then '记录已删除
bAddNew = True
GoTo ReTry
End If
End If
Exit Sub
E:
MsgBox Err.Description, vbCritical
End Sub
#4
谢谢“Tiger_Zhao”兄台