自动生成自定义序号的存储过程有问题,随机会出现重复序号,请大家帮忙给看看,感激不尽。
--获取id Id的格式为201312280001-201312289999
CREATE PROCEDURE prBuyMakeNewBuyID
@strToday varchar(50) --唯一的参数 格式为yyyymmdd,例如20131228 20140101
AS
set transaction isolation level serializable --加上最严格的隔离锁
begin transaction
declare @maxid varchar(50) --需要返回的序号
declare @tmpnum float --临时号码
select @tmpnum=convert(float,right(isnull(max(id), @strToday+'0000'),4)) from vwbuybuys where left(id,8)=@strToday --如果当日最大号码为20131228000,则临时号码为0 如果当日最大号码为
--201312280011,则临时号码为11
select @tmpnum=@tmpnum+1 --给临时号码加1
if @tmpnum<=9 and @tmpnum>=0
select @maxid=@strToday + '000' + convert(varchar(50),@tmpnum)
if @tmpnum<=99 and @tmpnum>=10
select @maxid=@strToday + '00' + convert(varchar(50),@tmpnum)
if @tmpnum<=999 and @tmpnum>=100
select @maxid=@strToday + '0' + convert(varchar(50),@tmpnum)
if @tmpnum<=9999 and @tmpnum>=1000
select @maxid=@strToday + convert(varchar(50),@tmpnum)
--将临时号码转换为4位,不够四位就前面加0 ,保证号码为四位
--然后将进来的唯一参数与转换后临时号码 组合到一起
declare @province varchar(100)
declare @city varchar(100)
declare @county varchar(100)
declare @company varchar(100)
declare @allownowsubweight int
select @province=province,@city=city,@county=county, @company=company from tbcommcompany
select @allownowsubweight=allownowsubweight from tbBuyControlArgs
if @allownowsubweight=1
begin
insert into tbbuybuys (id,inlock,assaylock,totalweightlock,carweightlock,nowsubweightlock,calclock, province,city,county1,company,carweightmicrochange,isup,othermark) values(@maxid,0,0,0,0,0,0,@province,@city,@county,@company,0,'未上传',0)
end
else
begin
insert into tbbuybuys (id,inlock,assaylock,totalweightlock,carweightlock,nowsubweightlock,calclock,province,city,county1,company,carweightmicrochange,isup,harlamount1,harlweight,meshamount1,meshweight,packsubweight,nowsubweight,othermark) values(@maxid,0,0,0,0,1,0,@province,@city,@county,@company,0,'未上传',0,0,0,0,0,0,0)
end
select @maxid
--关键是程序调用这个存储过程后,两个月内发生了8次返回的id与原来的id号码相同的问题
commit transaction
GO
--补充 这段代码使用了好多年了,就是最近软件开始将高清照片存入服务器后出的问题,每条记录4张照片大小大约共1MB,因为数据增长较快,数据库的大小在不断自动增长。这台服务器的内存是512M的联想服务器。
请大家帮忙!!!分数先给100,不够再看看如何补分。
[解决办法]
唯一代码取MAX+1逻辑表面上去看无甚问题, 但,
1. 并发性引起的问题嫌疑较大,可以在select @tmpnum=convert(float,right(isnull(max(id), @strToday+'0000'),4)) from vwbuybuys where left(id,8)=@strToday 再加一个行锁定with (rowlock)(尽管已经提高了事务级别);
2 可以在正式生成后后加一个exists唯一存在性查询...
3 这段代码可以重构,可以引起一张序列表来专门管理ID值,这样哪儿出错一目了然,也方便管理。。。
[解决办法]
select @tmpnum=convert(float,right(isnull(max(id), @strToday+'0000'),4)) from vwbuybuys where left(id,8)=@strToday
这个逻辑是不是,先求最大值,然后加1,这个在大量并发的时候,就会有重复值的。
你说之前用了很长时间,没问题,现在出现了重复值,估计可能是在插入 比较大的图片时,速度慢了,更容易导致重复出现了