***************SQL2K,D6 C/S 我想这样,当某用户修改数据时,锁定该记录,当另一用户试图修改该记录时,则向试图修改该记录的用

  • 主题发起人 主题发起人 蛐蛐
  • 开始时间 开始时间
帮你提一下
 
比较完善一些的做法:
1. 在每一个表上增加updateTime,updateUserId字段
2. 进入编辑画面时保留原来的这两个字段
3. 更新时在where中加入这两个字段条件
4. 更新失败后,可以立即读取updateUserId字段得到谁更改了纪录。
望大家讨论。
 
liuxianghui的方法是不入流的低级办法!如果标志表示正在更新,那么此时,更新记录的
那个客户掉线了,那标志永远保持着,这时不管谁都该不了了.这也叫办法?
 
只能关注,但不实用。
 
softdog 方法::

我把大致思路说一下:
在数据库中建立一个表:LockInfo,字段为:id int, LockTable varchar(20), LockRecID int等等
用以记录锁定信息。总体思路和skyweb描述的有点类似,但不同之处在于解锁方式,skyweb用的是手工
的方法,还要考虑客户端非正常断开时的情况。我的方法是这样的:
(说明:下面的描述语句是类SQL描述,不是真正的SQL语句)

锁定表:
LockInfo.BeginTrans
insert LockInfo(LockTable, LockRecID) values(表名, 记录ID)

判断锁定:
if exists(select id from LockInfo where LockTable=@LockTable and LockRecID=@LockRecID with nolock)
message: 已经被其他用户锁定(如果LockInfo表有足够的信息,可以检测到什么用户锁定)
else
message: 没有锁定

解锁:
LockInfo.RollbackTrans

大致思路:
某个客户端对数据库(MSSQL)中某个表进行修改之前如果开始了一个事务,则数据库会进行行锁,
即阻止其他用户存取该记录,但如果其他用户用“脏读”的方式来读取,则也可以看到该记录(修改后),
这样,在锁定时开始一个事务,并在LockInfo表中插入一条记录,此时不提交或回滚。如果其他用户用
“脏读”的方式能读取到该记录,则说明有锁定相应的表中的记录。当执行锁定的用户解锁时,只需回滚
事务即可。
在这种方式下,如果执行锁定的客户端非正常断开,数据库会自动回滚,相当于该客户端执行了解锁
操作。

对于数据库的事务和锁定我也只是懂点皮毛,上面的方法在大量客户端时不知会不会产生事务上的问题。
欢迎大家讨论!



你的这些是程序实现,还是在存储过程里实现,但在存储过程里你的事务如何嵌套??????
 
首先,必须使用缓冲更新,无论是TClentDataset还是TUpDateSQL,B/S结构更是如此.
编辑完毕保存时才启动事务,所有保存在事务中结束,保存结束必须提交或回滚.
其次,事务异常终止的处理方式是由数据库或事务调度系统完成的,可以设置立即回滚或者延时回滚.
出现长时间锁定记录的情况是设计不完善的结果.
开发的难度在于多条记录同时更新出错(脏数据冲突或其他异常)处理的完善性,要做一些细致的工作.
简单的方法,在保证数据整合性的前提下,只要对用户有一个相对合理的交待就可以了.
 
TO:Borinp
同意你的思路,让数据库长时间的保存未提交的事务是一种设计缺陷,
这会导致回滚段和资源锁的大量占用,其他用户等待时间得不到保证.
另外,ADO.NET中,Adaptor更新过程好像是用全部字段作为比较条件的,所以在其他用户修改记录后,
也会报告更新出错信息.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部