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

系统中使用语句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
1
同时开两个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大牛,为什么语句段一和语句段二的顺序对调后,就不会有重复了。

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

sql语句单据编号生成防并发的更多相关文章

  1. C# 生成编号(防并发)

    今天抽了点时间,写了一个通用的生成编号的程序! 我的生成规则为年月日+两位编号,即:yyyyMMdd+两位编号,譬如:2018101001 / 2018101002 / 2018101003 首先,一 ...

  2. MySQL通过SQL语句来直接生成新表

    1. 既复制表结构,也复制表数据 mysql> CREATE TABLE tmp_table SELECT * FROM dede_news; 说明:这种方法的缺点就是新表中没有了旧表的prim ...

  3. 在sqlserver中,使用sql语句更新数据库:生成随机数,更新每一行中的年龄字段

    use School --指定数据库 declare @min_id int --声明整数变量@x set @min_id=(select MIN(Id) from Students) --给变量@x ...

  4. SqlServer 中如何查看某一个Sql语句是复用了执行计划,还是重新生成了执行计划

    我们知道SqlServer的查询优化器会将所执行的Sql语句的执行计划作缓存,如果后续查询可以复用缓存中的执行计划,那么SqlServer就会为后续查询复用执行计划而不是重新生成一个新的执行计划,因为 ...

  5. mysqls,为node.js而编写的sql语句生成插件 (crud for mysql).

    It is written in JavaScript,crud for mysql.You can also use transactions very easily. mysqls 一款专为nod ...

  6. 年终巨献 史上最全 ——LINQ to SQL语句

    LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...

  7. LINQ to SQL语句大全

    LINQ to SQL语句大全     LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判 ...

  8. 史上最全 ——LINQ to SQL语句

    LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...

  9. LINQ to SQL语句(17)之对象加载

    对象加载 延迟加载 在查询某对象时,实际上你只查询该对象.不会同时自动获取这个对象.这就是延迟加载. 例如,您可能需要查看客户数据和订单数据.你最初不一定需要检索与每个客户有关的所有订单数据.其优点是 ...

随机推荐

  1. Joomla!网站扫描工具joomscan

    Joomla!网站扫描工具joomscan   Joomla!是一款知名的PHP语言编写的CMS系统.很多网站都使用Joomla!搭建而成.Kali Linux集成了一款Joomla!网站扫描工具jo ...

  2. 【kmp算法】模板

    void GetFail(char P[],int __next[])//__next[i]表示s[0]~s[i-1]的前缀中,最大长度相等的前后缀是多少 { __next[0]=-1; int le ...

  3. 【bzoj1370】【团伙】原来并查集还能这么用?!

    (画师当然是武内崇啦) Description 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1. 我朋友的朋友是我的朋友: 2. 我敌人的敌人是我的朋友: 所有是朋友的人组成一 ...

  4. 求一个整数个位数之和 Exercise06_02

    import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年下半年 * 题目:求一个整数个位数之和 * */ public class Exercise ...

  5. GAILS里面的SAVE方法

    用途 保存一个domain类的实例到数据库,需要的话会级联保存所有的子实例. 举例 def b = new Book(title:"The Shining") b.save() 描 ...

  6. React Native学习之DeviceEventEmitter传值

     使用DeviceEventEmitter前需添加 import { AppRegistry, StyleSheet, Text, View, DeviceEventEmitter } form 'r ...

  7. ueditor .net配置

    ASP.NET发展时期曾经诞生过 website  webapplication 两类程序. website 目前基本绝迹,就是曾经在App_Code目录中写代码,然后直接发布源码,动态编译的那种,基 ...

  8. Matlab与神经网络入门

    第一节.神经网络基本原理  1. 人工神经元( Artificial Neuron )模型  人工神经元是神经网络的基本元素,其原理可以用下图表示: 图1. 人工神经元模型 图中x1~xn是从其他神经 ...

  9. 如何让vs2017 EF实体生成支持Mysql 和 Oracle?

    1.Mysql 安装   MySql Connector/Net        https://dev.mysql.com/downloads/connector/net/ 安装    mysql f ...

  10. Delphi Thread

    Thread给几点说明:1.MyThread的实例作为TForm1的成员变量2.不要使用Form1这个全局变量,线程中可要使用它的Handle,你可以在Form中创建MyThread的实例时把Hand ...