首先我建立了一个这样的测试表: create table Card(F_CardNO varchar(20),F_Name varchar(20),F_Flag bit,F_Time datetime)
Go
insert Card(F_CardNo,F_Flag) select '1111-1111',0
insert Card(F_CardNo,F_Flag) select '1111-1112',0
insert Card(F_CardNo,F_Flag) select '1111-1113',0
insert Card(F_CardNo,F_Flag) select '1111-1114',0
insert Card(F_CardNo,F_Flag) select '1111-1115',0
insert Card(F_CardNo,F_Flag) select '1111-1116',0
insert Card(F_CardNo,F_Flag) select '1111-1117',0
insert Card(F_CardNo,F_Flag) select '1111-1118',0
insert Card(F_CardNo,F_Flag) select '1111-1119',0
insert Card(F_CardNo,F_Flag) select '1111-1110',0
Go然后先运行加有悲观锁的UPDATE代码: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:10'
-- 把刚才选择出来的卡进行注册.
update Card
set F_Name=user,
F_Time=getdate(),
F_Flag=1
where F_CardNo=@CardNo
commit
同时在另外一处运行没有加锁的UPDATE代码:declare @CardNo varchar(20)
Begin Tran
-- 选择一张未使用的卡
select top 1 @CardNo=F_CardNo
from Card
where F_Flag=0
-- 延迟50秒,模拟并发访问.
-- 把刚才选择出来的卡进行注册.
update Card
set F_Name=user,
F_Time=getdate(),
F_Flag=2
where F_CardNo=@CardNo
commit
请问这样我为什么修改的是一条记录,而不是两条记录啊???
Go
insert Card(F_CardNo,F_Flag) select '1111-1111',0
insert Card(F_CardNo,F_Flag) select '1111-1112',0
insert Card(F_CardNo,F_Flag) select '1111-1113',0
insert Card(F_CardNo,F_Flag) select '1111-1114',0
insert Card(F_CardNo,F_Flag) select '1111-1115',0
insert Card(F_CardNo,F_Flag) select '1111-1116',0
insert Card(F_CardNo,F_Flag) select '1111-1117',0
insert Card(F_CardNo,F_Flag) select '1111-1118',0
insert Card(F_CardNo,F_Flag) select '1111-1119',0
insert Card(F_CardNo,F_Flag) select '1111-1110',0
Go然后先运行加有悲观锁的UPDATE代码: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:10'
-- 把刚才选择出来的卡进行注册.
update Card
set F_Name=user,
F_Time=getdate(),
F_Flag=1
where F_CardNo=@CardNo
commit
同时在另外一处运行没有加锁的UPDATE代码:declare @CardNo varchar(20)
Begin Tran
-- 选择一张未使用的卡
select top 1 @CardNo=F_CardNo
from Card
where F_Flag=0
-- 延迟50秒,模拟并发访问.
-- 把刚才选择出来的卡进行注册.
update Card
set F_Name=user,
F_Time=getdate(),
F_Flag=2
where F_CardNo=@CardNo
commit
请问这样我为什么修改的是一条记录,而不是两条记录啊???
F_CardNo 唯一当然是更新一条了
waitfor delay '000:00:10'
很强大
原因很简单,你取得的F_CardNo是一样的。
直接 UPDATE TOP (1) Card SET F_Name = user, F_Time = GETDATE(), F_Flag = 2 WHERE Flag = 0 就行了