日期:2014-05-16  浏览次数:20415 次

SQL2000高并发下select取值重复的问题,希望有大神给予指导
现在有一个表A,大约20万数据。
需求是按给出次数从少到多排序,每次请求给出100行数据,高并发下不重复。

我现在的方案是

    begin tran
    select top 100 id from A with (rowlock,readpast) order by getnum
    (之前加过newid(),虽然取随机记录大大降低并发率,但是CPU有点吃不消,所以放弃)
    然后游标
    update A set getnum=getnum+1 where id=@id --更新给出次数
    @allid=@allid+','+@id --记录所有取出的ID
    commit tran
    select * from A where id in (@allid) --返回此次取出记录的记录集

但是测试结果依旧频繁发生取出重复值的情况 也试过set transaction isolation level serializable 当然也有可能是我用的不对,毕竟SQL不是我专业,所以在此请教各位大师,如果想实现我想要的功能,应该怎么写?之前提问过几次,由于描述不是很清晰,得到的答案总是未能解决我的问题。
------解决方案--------------------
改成这样试试:WITH (UPDLOCK, HOLDLOCK)
------解决方案--------------------
修改了一下,注释了一下:
create table t(id numeric(10,0))

--只有1条记录
 insert into t  
 values(0)
go


 declare @id numeric(10,0)
 declare @c numeric(10,0)
 
 select @id = id from t with(updlock)  --取出1条数据
 
select @c = COUNT(*) from a   --取出a表中记录总数
 

 update t
 set t = case when (id + 100) % @c < 100 then 0 
              else  (id + 100) % @c 
         end --更新这条记录,比如一开始是0,那么经过计算就是100


--选出第i+1 ~ i+100,比如一开始i是0,那么就是1~100
 select id
 from 
 (
 select id,row_number() over(order by getnum) rownum from A
 )t
 where rownum between @id+1 and @id+100
 
 



你这个代码,用了动态语句,还在动态语句中写游标,看着也挺晕的。。。
------解决方案--------------------
引用:
Quote: 引用:

增加一个guid字段,取消游标
declare @g guid
set @g=newid()
update a
set fguid=@g,getnum=getnum+1
where id in
(select top 100 id from a order by getnum,id)

select * from a where fguid=@g

第 -1 个列或参数: 无法找到数据类型 guid。
参数 '@g' 的数据类型无效。


sql2000可能还没这个类型?
那就使用 系统时间到毫秒+随机数 的字符串做@g。。。。

不对,你不是说 用过newid()吗?应该就是它的类型就行了