探讨SQL Server并发处理队列数据不阻塞解决方案
前言
之前对于并发这一块确实接触的比较少,自从遇到现在的老大,每写完一块老大都会过目一下然后给出意见,期间确实收获不少,接下来有几篇会来讲解SQL Server中关于并发这一块的内容,有的是总结,有的是学习,若有错误见解请批评性指出。
SQL Server并发处理队列数据问题
在我们的项目中对于购买产品的用户会对应分配卡密,同时会更新其卡密的状态为已使用,所以当出现并发时此时我们不加以控制会导致同一个卡号和密码被不同的用户所使用,这样的情况是不能允许的,此时我们迫切需要解决对卡密使用后的更新和产生的并发。所以有了此文的产生。我们接下来来创建测试表。
CREATE TABLE Test (
Id INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
Other VARCHAR(100)) GO
接下来我们插入十条测试数据
DECLARE @counter INT SELECT @counter = 1 WHILE (@counter <= 10)
BEGIN
INSERT INTO Test
(Other)
SELECT 'other action' + CAST(@counter AS VARCHAR) SELECT @counter = @counter + 1
END
接下来我们打开两个会话运行如下SQL语句:
DECLARE @queueid INT BEGIN TRAN TRAN1 SELECT TOP 1 @queueid = Id
FROM Test PRINT 'processing queueid # ' + CAST(@queueid AS VARCHAR) WAITFOR DELAY '00:00:10' DELETE FROM Test
WHERE Id = @queueid COMMIT
此时我们看到打开的两个会话会同时处理相同的行。
如上则不是我们想要的结果,此时我们再来在如上基础上加一个更新锁,然后SQL Server查询引擎会不允许其他读取者来获取更新锁,此时将能够有效的处理对应对应的行记录,但是会造成阻塞,如下:
DECLARE @queueid INT BEGIN TRAN TRAN1 SELECT TOP 1 @queueid = Id
FROM Test WITH (updlock) PRINT 'processing queueid # ' + CAST(@queueid AS VARCHAR) WAITFOR DELAY '00:00:10' DELETE FROM Test
WHERE Id = @queueid COMMIT
上述虽然能解决更新问题,但是此时会造成阻塞,一旦并发量比较大此时将造成长时间阻塞,当前正在执行的更新会话必须等待另外一个更新会话执行完毕同时释放更新锁。此时为了解决阻塞问题,在SQL Server中通过添加READPAST关键字来告诉SQL Server引擎一旦遇到被锁住的行,你就跳过吧不用理会,所以不会再造成阻塞问题。此时最终的代码将变成如下:
DECLARE @queueid INT BEGIN TRAN TRAN1 SELECT TOP 1 @queueid = Id
FROM Test WITH (updlock) BEGIN TRAN TRAN1 SELECT TOP 1 @queueid = Id
FROM Test WITH (UPDLOCK, READPAST) PRINT 'processing queueid # ' + CAST(@queueid AS VARCHAR) WAITFOR DELAY '00:00:10' DELETE FROM Test
WHERE Id = @queueid COMMIT PRINT 'processing queueid # ' + CAST(@queueid AS VARCHAR) WAITFOR DELAY '00:00:10' DELETE FROM Test
WHERE Id = @queueid COMMIT
通过UPDLOCK+READPAST结合使用将对于处理并发更新时,就像处理队列数据一样,但是不会造成阻塞,此时将给予我们最好的性能。我们结合上述所讲,来查询出数据并删除对应数据且,不会出现重复删除情况且不会导致阻塞,此时代码将变成如下:
SET NOCOUNT ON
DECLARE @queueid INT WHILE (SELECT COUNT(*) FROM Test WITH (updlock, readpast)) >= 1 BEGIN BEGIN TRAN TRAN1 SELECT TOP 1 @queueid = Id
FROM Test WITH (updlock, readpast) PRINT 'processing queueid # ' + CAST(@queueid AS VARCHAR) WAITFOR DELAY '00:00:10' DELETE FROM Test
WHERE Id = @queueid
COMMIT
END
总结
本文我们探讨产生并发在SQL Server中如何不处于阻塞并且得到较好的性能,对于那种秒杀情况,这种方案不失为一种解决方案,请问你有何高见?
探讨SQL Server并发处理队列数据不阻塞解决方案的更多相关文章
- 探讨SQL Server并发处理存在就更新七种解决方案
前言 本节我们来讲讲并发中最常见的情况存在即更新,在并发中若未存在行记录则插入,此时未处理好极容易出现插入重复键情况,本文我们来介绍对并发中存在就更新行记录的七种方案并且我们来综合分析最合适的解决方案 ...
- SQL Server中SELECT会真的阻塞SELECT吗?
在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.T ...
- SQL Server ->> 深入探讨SQL Server 2016新特性之 --- Temporal Table(历史表)
原文:SQL Server ->> 深入探讨SQL Server 2016新特性之 --- Temporal Table(历史表) 作为SQL Server 2016(CTP3.x)的另一 ...
- Sql Server系列:数据表操作
表是用来存储数据和操作数据的逻辑结构,用来组织和存储数据,关系数据库中的所有数据都表现为表的形式,数据表由行和列组成.SQL Server中的数据表分为临时表和永久表,临时表存储在tempdb系统数据 ...
- 一个有趣的SQL Server 层级汇总数据问题
看SQL Server大V宋大侠的博客文章,发现了一个有趣的sql server层级汇总数据问题. 具体的问题如下: parent_id emp_id emp_nam ...
- sql server 随机读取数据
--sql server 随机读取数据 * FROM [tablename] ORDER BY NEWID() pk from [tablename] ORDER BY NEWID()) --这两个方 ...
- sql server 与oracle数据互导的一种思路--sql server链接服务器
思路:通过在sql server数据库中添加链接服务器,可以远程查询oracle数据库的表环境准备,安装sql server数据库,并安装好oracle驱动,在配置好tnsname文件中配置好orac ...
- 如何用asp.net MVC框架、highChart库从sql server数据库获取数据动态生成柱状图
如何用asp.net MVC框架.highChart库从sql server数据库获取数据动态生成柱状图?效果大概是这样的,如图: 请问大侠这个这么实现呢?
- 最简单删除SQL Server中所有数据的方法
最简单删除SQL Server中所有数据的方法 编写人:CC阿爸 2014-3-14 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间 ...
随机推荐
- WebGL 创建和初始化着色器过程
1.编译GLSL ES代码,创建和初始化着色器供WebGL使用.这些过程一般分为7个步骤: 创建着色器对象(gl.createBuffer()); 向着色器对象中填充着色器程序的源代码(gl.shad ...
- scss实现不同方向的三角
//定义一个三角的函数 实现不同方向的三角加兼容ie6//第一个参数传入方向//第二个参数传入大小//第三个参数传入颜色//注意:传入参数中间必须逗号分隔@mixin triangle($x, $y: ...
- 【模板】链式前向星+spfa
洛谷传送门--分糖果 博客--链式前向星 团队中一道题,数据很大,只能用链式前向星存储,spfa求单源最短路. 可做模板. #include <cstdio> #include <q ...
- mapTask并行度优化及源码分析
mapTask并行度的决定机制 一个job的map阶段并行度由客户端在提交job时决定,而客户端对map阶段并行度的规划的基本逻辑为:将待处理数据执行逻辑切片(即按照一个特定切片大小,将待处理数据划分 ...
- 搜索结果Refinement 行为总结之 multi-selection refinement
几乎所有的购物网站的搜索结果页面都会提供refinement (filtering) 给用户去过滤产品,以便能更快找到自己想要的产品.(做的都是国外的项目,不太清楚这个功能地道的中文名是什么.所以就暂 ...
- 2017河工大校赛补题CGH and 赛后小结
网页设计课上实在无聊,便开始补题,发现比赛时候僵着的东西突然相通了不少 首先,"追妹"这题,两个队友讨论半天,分好多种情况最后放弃(可是我连题目都没看啊),今天看了之后试试是不是直 ...
- python基本数据类型——int
一.int的范围 python2: 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1: 在64位系统上,整数的位数为64位,取值范围为-2**63-2**63-1: pyth ...
- linq语句复杂查询和分开查询的性能对比
刚开始以为复杂的linq语句查询会不会比分开来写效率高,因为复杂的语句关联和嵌套多,执行应该慢.分开写虽然多了一次io处理,但是关联比较少,数据了比价少,和朋友讨了一下,回家就做了个测试,废话不多说, ...
- Angular杂谈系列2-Angular2升级Angular4指南
什么什么?Angualr4都发布了,之前不都才Angualr2的么?又要推翻重来,啊? 那当然不是,Angualr4只是一个版本号而已,本质上还是Angular2:以后,谷歌把新版本的Angualr称 ...
- Python 基础 四 面向对象杂谈
Python 基础 四 面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...