存储过程数据并发问题

赵凯~ 2008-08-26 10:32:54
create proc P_GetPrize
@count int
AS
SET LOCK_TIMEOUT 2000
SET XACT_ABORT ON
SET NOCOUNT ON
begin tran
此处修改字段number=number+1
IF(@@ERROR<>0)
BEGIN
SELECT NULL
ROLLBACK TRAN
END
COMMIT TRAN
if(@count=number)--number为上面修改后的值
该用户中奖




问题:比如我传递的@count=111 为什么if(@count=number)同时会有两个人中奖呢
肯定是数据并发的问题,怎么解决呀?谢谢了!!!

...全文
116 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵凯~ 2008-08-26
  • 打赏
  • 举报
回复
数据并发
赵凯~ 2008-08-26
  • 打赏
  • 举报
回复
ALTER PROCEDURE [dbo].[P_WOWSUMMER_GetPrize_GetPrize]
@Type int,-- 活动类型
@Sequence varchar(12),
@LoginName varchar(50),
@WitchNum int,--前台根据时间段传递的中奖者数字 比如500即第500个人中A奖
@CPUNum int,--前台根据时间段传递的中奖者数字 比如200即第200个人中B奖
@NickName varchar(50),
@WitchDate datetime,--前台配置中A奖时间
@CPUDate datetime--前台配置中B奖时间

AS

SET LOCK_TIMEOUT 2000
SET XACT_ABORT ON
SET NOCOUNT ON

--用户如果已经获得了大奖 则返回避免重复中奖
if exists(select * from WOWSUMMER_GetPrize where LoginName=@LoginName and [Type]=@Type and Status=1)
begin
select * from WOWSUMMER_GetPrize where LoginName=@LoginName and [Type]=@Type and Status=1 return 0
end
--修改prize 表的PrizeStatus=1 表示此人已经敲箱子
begin
begin tran
update WOWSUMMER_PRIZE set PrizeStatus=1 where Sequence=@Sequence
IF(@@ERROR<>0)
BEGIN
SELECT NULL
ROLLBACK TRAN
END
COMMIT TRAN
end
declare @flag varchar(10)
declare @prizerID int
declare @usercount_witch int--当天敲箱子的巫妖王帐号数量
declare @usercount_cpu int--当天敲箱子的CPU帐号数量
set @usercount_witch=(select count(*) from WOWSUMMER_PRIZE where [Type]=@Type and Status>0 and datediff(day,@WitchDate,UpdateTime)=0 and PrizeStatus=1)
set @usercount_cpu=(select count(*) from WOWSUMMER_PRIZE where [Type]=@Type and Status>0 and datediff(day,@CPUDate,UpdateTime)=0 and PrizeStatus=1)
set @flag='error'
if(@usercount_witch=@WitchNum)
begin
set @prizerID=(select top 1 [ID] from WOWSUMMER_GetPrize where [Type]=@Type and Status=0 and ItemType=1)
set @flag='ok'
end
else if(@usercount_cpu=@CPUNum)
begin
set @prizerID=(select top 1 [ID] from WOWSUMMER_GetPrize where [Type]=@Type and Status=0 and ItemType=2)
set @flag='ok'
end
if(@flag='ok')
begin
begin tran

update WOWSUMMER_GetPrize set Status=1, LoginName=@LoginName ,NickName=@NickName,Sequence=@Sequence, GetPrizeDate=getdate() where [ID]=@prizerID
IF(@@ERROR<>0)
BEGIN
SELECT NULL
ROLLBACK TRAN
END
COMMIT TRAN
end
select * from WOWSUMMER_GetPrize where LoginName=@LoginName and [Type]=@Type and Status=1 order by GetPrizeDate desc


我大概描述下哦:
1)两张表prize(奖品表prizestatus表示该用户是否敲箱子)getprize(中奖表)事先往表里插入有11条status=0的记录 当有人中奖时把status=1直至11个人全部中完为止
2)奖品分A和B两类 
3)中奖条件为:某天第几个敲箱子的人会中奖

问题是:理论上@usercount_witch=@WitchNum只有1个人会发生 实际上有2个人

谢谢
bwu851 2008-08-26
  • 打赏
  • 举报
回复
LOCK_TIMEOUT --- 是表示你能在某资源上放置lock多长时间.

XACT_ABORT --- 表示如果下面的transaction出现错误, 就终止并回滚.

你看看那条是你想要的只允许一个用户调用该存储过程??

还真没听说过能限制只让一个用户调用存储过程的(除非你设定了权限).
brio8425 2008-08-26
  • 打赏
  • 举报
回复
更新数据会产生一个更新锁。
flairsky 2008-08-26
  • 打赏
  • 举报
回复
service broker
bwu851 2008-08-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 dongbeimao123 的回复:]
SET LOCK_TIMEOUT 2000
SET XACT_ABORT ON
SET NOCOUNT ON
能起到加锁的目的吗?
其实我的想法是同一时间只有1个用户调用该存储过程
[/Quote]

起不到你要的效果.
bwu851 2008-08-26
  • 打赏
  • 举报
回复
你应该查查....有几个人:

select count(*)
from table_name
where number = 110
昵称被占用了 2008-08-26
  • 打赏
  • 举报
回复
要么写全代码,要么全部文字描述(相信自己的文字描述能力)
现在这样根本看不懂
赵凯~ 2008-08-26
  • 打赏
  • 举报
回复
SET LOCK_TIMEOUT 2000
SET XACT_ABORT ON
SET NOCOUNT ON
能起到加锁的目的吗?
其实我的想法是同一时间只有1个用户调用该存储过程

22,302

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧