sql语句单据编号生成防并发
有用户反馈说发现重复单据号,检查发现以下单据号被分配给了不同的两个职工
系统中使用语句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语句单据编号生成防并发的更多相关文章
- C# 生成编号(防并发)
今天抽了点时间,写了一个通用的生成编号的程序! 我的生成规则为年月日+两位编号,即:yyyyMMdd+两位编号,譬如:2018101001 / 2018101002 / 2018101003 首先,一 ...
- MySQL通过SQL语句来直接生成新表
1. 既复制表结构,也复制表数据 mysql> CREATE TABLE tmp_table SELECT * FROM dede_news; 说明:这种方法的缺点就是新表中没有了旧表的prim ...
- 在sqlserver中,使用sql语句更新数据库:生成随机数,更新每一行中的年龄字段
use School --指定数据库 declare @min_id int --声明整数变量@x set @min_id=(select MIN(Id) from Students) --给变量@x ...
- SqlServer 中如何查看某一个Sql语句是复用了执行计划,还是重新生成了执行计划
我们知道SqlServer的查询优化器会将所执行的Sql语句的执行计划作缓存,如果后续查询可以复用缓存中的执行计划,那么SqlServer就会为后续查询复用执行计划而不是重新生成一个新的执行计划,因为 ...
- mysqls,为node.js而编写的sql语句生成插件 (crud for mysql).
It is written in JavaScript,crud for mysql.You can also use transactions very easily. mysqls 一款专为nod ...
- 年终巨献 史上最全 ——LINQ to SQL语句
LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...
- LINQ to SQL语句大全
LINQ to SQL语句大全 LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判 ...
- 史上最全 ——LINQ to SQL语句
LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...
- LINQ to SQL语句(17)之对象加载
对象加载 延迟加载 在查询某对象时,实际上你只查询该对象.不会同时自动获取这个对象.这就是延迟加载. 例如,您可能需要查看客户数据和订单数据.你最初不一定需要检索与每个客户有关的所有订单数据.其优点是 ...
随机推荐
- RPD Volume 168 Issue 4 March 2016 评论7-end
Shielding activation of petawatt laser facilities in Romania: a FLUKA preliminary evaluation Abstr ...
- MySQL笔记之视图的使用详解
原文:http://www.jb51.net/article/36363.htm 1.什么是视图 视图是从一个或多个表中导出来的表,是一种虚拟存在的表. 视图就像一个窗口,通过这个窗口可以看到系统专门 ...
- 1.4(Spring MVC学习笔记)JSON数据交互与RESTful支持
一.JSON数据交互 1.1JSON简介 JSON(JavaScript Object Notation)是一种数据交换格式. 1.2JSON对象结构 {}代表一个对象,{}中写入数据信息,通常为ke ...
- Exercise01_01
public class print{ public static void main(String[] args){ System.out.println("Welcome to Java ...
- Matlab设置字体大小
1. 设置坐标轴上下限:axis([xmin,xmax,ymin,ymax]); 2. 设置图片大小:set(gcf,'Position',[x1,y1,dx,dy]); x1和y1是图的左下角坐 ...
- spring集成redis,集成redis集群
原文:http://chentian114.iteye.com/blog/2292323 1.通过spring-data-redis集成redis pom.xml依赖包 <project xml ...
- linux 账户锁与解锁
,sudo passwd -l user 锁住user帐号,su 已经不能切换到user下. 2,sudo passwd -u user 解锁user帐号,su可以切换到user下. 3,如果不小心把 ...
- linux如何安装xampp,以及融合dvwa
1.官网下载:https://www.apachefriends.org/download.html 2.赋予执行权限 [admin@19-56 ~]$ chmod +x xampp-linux-x6 ...
- [Python爬虫] 之二十三:Selenium +phantomjs 利用 pyquery抓取智能电视网数据
一.介绍 本例子用Selenium +phantomjs爬取智能电视网(http://news.znds.com/article/news/)的资讯信息,输入给定关键字抓取资讯信息. 给定关键字:数字 ...
- Docker解析及轻量级PaaS平台演练(四)--Fig相关介绍
本篇中将会使用开源工具Fig Fig是什么? 简单的说就是对Docker的封装,从而方便我们构建应用的运行环境 它所做的事情是协调Docker上的各个Container之间的联系,并通过服务发现的方式 ...