读书人

说说在处理WEB数据更新时怎么保证只

发布时间: 2012-01-06 22:55:18 作者: rapoo

说说在处理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)


begin
print '此卡已经被另外一个用户注册! '
rollback tran
end
else
begin
print '并不存在此卡! '
rollback tran
end
end

[解决办法]
在另外一个窗口里边执行没有waitfor的代码,注册成功后,返回原来的窗口,我们就会发现到时间后它显示的提示是此卡以被另外一个用户注册的提示.很明显,这样我们也可以避免两个用户同时注册一张卡的现象的出现.同时,使用这种方法的另外一个好处是没有使用更新锁,这样增加的系统的并发处理能力.

[解决办法]
你可以先把这条记录的id放到一个表中,编辑的时候先判断表中是否已经有id了,有的话表示记录正在编辑,编辑完成后然后把id从表中删除。 当然, 为了预防异常情况,你必须有解锁的功能。比方说,当id在出现异常的时候不能从表中删除,那你必须提供一个机制把这个id从表中删除。

另一种方式是加一个version列,每更新一次version就加1, 当然这种情况允许同时编辑,但更新的时候你可以选择覆盖更新还是拒绝更新。

[解决办法]
哈哈,楼上的签名太搞了吧,俺猜是尸变的可能比较大,捏盘可能很小哦:)
[解决办法]
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

[解决办法]
sql2000是用锁实现的事务,但sql2005和oracle都是用版本控制来实现事务的。
‘其它人正在更新一条记录时其它用户就不允许更新此条记录’这个只能让事务来控制(取决于具体的隔离级别),例如这个更新过程意外的很长,这时另一个人来更新,怎么办。他如何知道这个记录正在更新。
[解决办法]
UP`
[解决办法]
学习
[解决办法]
我有个笨方法,在数据库中再建个表,有ID,TABLENAME,TABLEID,如果你要是编辑类先判断在这个表是不是有了,没有就把某条类就插进去,再写个触发,过了5分钟就把某条删了,这样就不会死锁了,当你编辑完了也把这条删了,记得给分呀

读书人网 >asp.net

热点推荐