zoukankan      html  css  js  c++  java
  • 生成了重复的唯一单据号?

    有用户反馈说发现重复单据号,检查发现以下单据号被分配给了不同的两个职工

    系统中使用语句exec GetNewOrderNumber 'pwgnumber','PWG',1, @pwg_number output

    来产生唯一单据号

    此存储过程中获取最大值的语句如下:

    if exists(select * from s_systemset(nolock) where classname=@keyname and typename=@keyvalue)      
      begin      
        begin tran
    --语句段1
    select @ordernumber=typename+substring(replicate('0',convert(int,8))+itemvalue,
           len(replicate('0',conv     ert(int,8))+itemvalue)-(convert(int,8)-1),convert(int,8))     
        from s_systemset(nolock)    
        where classname=@keyname      
          and typename=@keyvalue      
    --语句段2          
        update s_systemset       
        set itemvalue=itemvalue+1    
        from s_systemset        
        where classname=@keyname      
          and typename=@keyvalue      
        commit tran    
      end 
    同时开两个SQL查询窗口执行以下语句

    窗口一:waitfor delay '00:00:05'
    print '1'
    declare @ordernumber varchar(20),@i int=1,@sysid int=1
    while @i<=31000
    begin
    exec TestNewOrderNumber 'testnumber','TST',1,@ordernumber output
    insert into test_log(docnumber,sysid,indate)
    values (@ordernumber,@sysid,GETDATE())
    set @i=@i+1
    end

    窗口二:

    waitfor delay '00:00:06'
    print '2'
    declare @ordernumber varchar(20),@i int=1,@sysid int=2
    while @i<=32000
    begin
    exec TestNewOrderNumber 'testnumber','TST',1,@ordernumber output
    insert into test_log(docnumber,sysid,indate)
    values (@ordernumber,@sysid,GETDATE())
    set @i=@i+1
    end

    检查是否有重复:

    select docnumber,COUNT(docnumber)
    from test_log
    group by docnumber
    having COUNT(docnumber)>=2

    测试结果如下:有8条记录重复。

      

    在两个不同用户同一秒调用此语句后,产生了重复的Pwg_Number,为什么呢?

    在SQL中已经用了事务来获取最大值,为何不同用户几乎同时调用时会返回相同的pwg_number?

    尝试将语句段1和语句段2对调如下:

    --将语句段1和语句段2对调
    begin tran    
        update s_systemset   --语句段2    
        set itemvalue=itemvalue+1    
        from s_systemset        
        where classname=@keyname      
          and typename=@keyvalue 
        --语句段1  
        select @ordernumber=typename+substring(replicate('0',convert(int,8))+itemvalue,len(replicate('0',convert(int,8))+itemvalue)-(convert(int,8)-1),convert(int,8))     
        from s_systemset(rowlock) --将nolock改为rowlock   
        where classname=@keyname      
          and typename=@keyvalue      
    
        commit tran

    重复在两个窗口并行测试,第一次是9万笔,第二次是90万笔,第3次10万笔。统计没有重复记录。

    到这里重复单据号的问题是否算是已经得到解决了呢?

    各位SQL大牛,为什么语句段一和语句段二的顺序对调后,就不会有重复了。

     问题来了,以上语句真得能够保证产生唯一的最大值吗?

  • 相关阅读:
    Linux下MySQL主从同步配置
    Tortoisegit图文使用教程
    C语言I博客作业06
    第十周助教总结
    C语言I博客作业04
    C语言I博客作业02
    第十一周助教总结
    第十二周助教总结
    第九周助教总结
    C语言I博客作业02
  • 原文地址:https://www.cnblogs.com/tonylong/p/4280873.html
Copyright © 2011-2022 走看看