说说在处理WEB数据更新时,如何保证只有一个用户在编辑某一条记录?
我没有使用时间戳,那样是在提交数据时判断,我使用的是在需要唯一更新的表上加一个时间字段,该字段用来记录最后一次更新该记录的时间,比如说现在要更新的记录的时间字段值为2007-01-01 1:00:00,预先定义的操作超时时间间隔为20分钟,如果操作时间与记录中的时间字段相比较未超出定义的超时间隔,则认为有人在编辑该条记录,否则则认为可以编辑超时记录。
说说大家在处理这样的操作时是如何做的?
------解决方案--------------------帮顶
------解决方案--------------------友情幫頂
------解决方案--------------------在页面上控制好像不可能了,不过数据库有保证并发的机制呀!不知楼主意欲何为?
如果想保证你所说的那种情况,个人认为可以数据库中加个标记列,为真时保证它可编辑,否则不可编辑
------解决方案--------------------可以设置一application对象来记录正在编辑的记录,任何一个用户编辑一条记录时,都去判断application里是否有该条记录的id,如果有,就不允许编辑,没有就允许,编辑完保存后,从application里删除该记录的id
------解决方案--------------------可以从数据库着手去考虑这个问题,例如使用表锁,记录的标识等。
------解决方案--------------------额外建立一个表,记录所有被编辑的记录,其他人打开编辑记录时首先进行检测,如果存在则提示锁定。
直接利用数据库好像不怎么好吧~~不知道怎么控制
------解决方案--------------------不可行,
最基本的做法就是用事务处理
------解决方案--------------------持继关注...
------解决方案--------------------这种情况必然存在,只能处理,不能保证。
只能用事务,在数据库中单纯的判断怎么都不行,脏读,重复读的情况解决不了。
------解决方案--------------------悲观锁定解决方案
-- 我们只要对上边的代码做微小的改变就可以实现悲观的锁定.
declare @CardNo varchar(20)
Begin Tran
-- 选择一张未使用的卡
select top 1 @CardNo=F_CardNo
from Card with (UPDLOCK) where F_Flag=0
-- 延迟50秒,模拟并发访问.
waitfor delay '000:00:50 '
-- 把刚才选择出来的卡进行注册.
update Card
set F_Name=user,
F_Time=getdate(),
F_Flag=1
where F_CardNo=@CardNo
commit
------解决方案--------------------关注
------解决方案--------------------在查询的时候使用了with (UPDLOCK)选项,在查询记录的时候我们就对记录加上了更新锁,表示我们即将对次记录进行更新.注意更新锁和共享锁是不冲突的,也就是其他用户还可以查询此表的内容,但是和更新锁和排它锁是冲突的.所以其他的更新用户就会阻塞.如果我们在另外一个窗口执行此代码,同样不加waifor delay子句.两边执行完毕后,我们发现成功的注册了两张卡.可能我们已经发现了悲观锁定的缺点:当一个用户进行更新的事务的时候,其他更新用户必须排队等待,即使那个用户更新的不是同一条记录.
------解决方案-------------------- 乐观锁定解决方案
-- 首先我们在Card表里边加上一列F_TimeStamp 列,该列是varbinary(8)类型.但是在更新的时候这个值会自动增长.
alter table Card add F_TimeStamp timestamp not null
declare @CardNo varchar(20)
declare @timestamp varbinary(8)
declare @rowcount int
Begin Tran
-- 取得卡号和原始的时间戳值
select top 1 @CardNo=F_CardNo,
@timestamp=F_TimeStamp
from Card
where F_Flag=0
-- 延迟50秒,模拟并发访问.
waitfor delay '000:00:50 '
-- 注册卡,但是要比较时间戳是否发生了变化.如果没有发生变化.更新成功.如果发生变化,更新失败.
update Card
set F_Name=user,
F_Time=getdate(),
F_Flag=1
where F_CardNo=@CardNo and F_TimeStamp=@timestamp
set @rowcount=@@rowcount
if @rowcount=1
begin
print '更新成功! '
commit
end
else if @rowcount=0
begin
if exists(select 1 from Card where F_CardNo=@CardNo)