SQL两个事务update同一张表出现的死锁问题(waitfor delay)
抄录网址:https://blog.csdn.net/qiumuxia0921/article/details/50574879
下面是我们的建表语句:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[table1](
[A] [nvarchar](10) NULL,
[B] [nvarchar](10) NOT NULL,
[C] [nvarchar](10) NULL
) ON [PRIMARY]
GO INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa1', N'b1', N'')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa2', N'b3', N'')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b4', N'')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b5', N'')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b2', N'')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b6', N'')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b7', N'')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa3', N'b8', N'')
INSERT [dbo].[table1] ([A], [B], [C]) VALUES (N'aa1', N'b9', N'')
我们第一个update事务为:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
begin tran
print convert(nvarchar(30),convert(datetime,getdate(),121),121)
update t_table
set A='aa1'
where B='b3'
print convert(nvarchar(30),convert(datetime,getdate(),121),121)
EXEC sp_lock @@spid waitfor delay '00:00:05' update t_table
set A='aa2'
where B='b8'
EXEC sp_lock @@spid
print convert(nvarchar(30),convert(datetime,getdate(),121),121)
commit tran
第二个update事务为:
SET TRANSACTION ISOLATION LEVEL Read UNCOMMITTED
begin tran
update table1
set A='aa3'
where B='b1'
EXEC sp_lock @@spid
commit tran
两个事物首先我们触发事务一,然后紧接着,我们触发事务二,这个时候,消息中出现:死锁。
我们首先看一下现在table1表中的数据,我们把数据放到Excel中进行分析:
Process Node1 :
首先我运行事务一(Process Node1),我们看看它的代码:update table1 set A='aa1' where B='b3' ,系统运行这一步的时候,是从第一条数据开始加上U锁的,当检查到第二条数据的时候,U锁发现,符合B='b3'时,将U锁升级为X锁,这个时候,我们就在第一条蓝线这里表示为X,接下来,继续对第3条记录进行U锁,然后为第4条,第5条,到了第11条的时候,又存在了符合B='b3'时,将U锁升级为X锁,也就是我表示的第二条蓝线,继续加U锁,发现,整张表都已经所扫描完了,没有存在符合条件的了,这个时候,如果Process Node1到这里就运行完了,我们应该释放X锁,但是Process Node1,后面还有代码:waitfor delay '00:00:10' ,也就是等待了10秒钟,这个时候,只要事务不执行完成,X锁不会释放。
Process Node2 :
而此时,我已经运行了事务二,我们看到它的代码是: update table1 set A='aa3' where B='b1',通过上面说明,我们同样分析一下该update语句的执行过程,Process Node2将table1中的数据从第一条开始加U锁,这个时候,第一条数据就符合 B='b1',这个时候,U锁升级为X锁,继续往下执行的时候,发现第二条数据已经被Process Node1的X锁占有,X锁为排它锁的原因为不与其他锁兼容,也就是说,不能加U锁,这个时候,Process Node2只能等待Process Node1将X锁释放,而Process Node1 没有执行完成,是不会释放X锁的,所以Process Node2 等待Process Node1释放第二条记录的X锁。
Process Node1:
这个时候,我们发现Process Node1中waitfor delay '00:00:10' ,代码已经运行完成,之后,进行update table1 set A='aa2' where B='b8'代码,这条语句从第一条数据开始加U锁,但是,我们发现第一条数据已经被Process Node2的X锁占用,也就是说,Process Node1需要等待Process Node2 的X锁释放才行,所以Process Node1 在第一条记录这里等待。
我们最后看到的应该是这样的:
因此出现了上面的现象,就是Process Node2 想要对Resource Node1(第二条记录)请求U锁,但是,Resource Node1 被Process Node1 的X锁占用,
而Process Node2 想要对Resource Node2(第一条记录)请求U锁,但是Resource Node2被Process Node2 的X锁占用。
解决方案:
在B的字段加上非聚集索引,就可以了。
因为聚集索引和非聚集索引加U锁的时候,都不是整张表进行扫描的,而是直接就可以根据索引找到这条记录进行升级锁,所以,不会出现上面的死锁的问题。
SQL两个事务update同一张表出现的死锁问题(waitfor delay)的更多相关文章
- 两个事务 update同一张表出现的死锁问题 (转载)
引言 近来做省一级计算机一级考试系统的时候,学生端进行大批量判分的时候,出现了这样的问题(事务(进程 ID 262)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品.请重新运行该事务.): 这 ...
- sqlserver默认隔离级别下并发批量update同一张表引起的死锁
提到死锁,最最常规的场景之一是Session1 以排它锁的方式锁定A表,请求B表,session2以排它锁的方式锁定B表,请求A表之类的,访问顺序不一致导致死锁的情况本文通过简化,测试这样一种稍显特殊 ...
- 怎么用sql语句查询一个数据库有多少张表
今天在技术群中闲谈时忽然聊到一个问题,那就是当一个数据库中有多张表时怎么快速的获取到表的个数,从而给问询者一个准确的回答. 大家或许会说,这个问题和我们的数据库操作没有太大关系或者不是很挂钩,所以没意 ...
- 级联两个bootstrap-table。一张表显示相关的数据,通过点击这张表的某一行,传过去对应的ID,刷新另外一张表。
二张表的代码(我用的插件,大家可以去网上直接下载http://issues.wenzhixin.net.cn/bootstrap-table/): <div class="contai ...
- EF——一个实体对应两张表,两个实体对应一张表 06 (转)
本篇日记我们将详细探讨如何将表现领域的类映射到现有的数据库.现在的经济形势不是太好,很多公司都取消了开发新系统的预算.在这种情况下,通常的做法是把原有的几个系统修改一下做个集成,先凑合用着得了.如果要 ...
- sql语句左链接left join--3张表关联
表A---------------------------------关联第一张表B-----------------------关联第二张表c select * fomr 表名A left join ...
- Sql Server两个数据库中有一张表的结构一样,怎么快速将一张表中的数据复制到另一个表中
1,下面这句会把表2数据删除,然后把表1复制到表一,两表内容一样 SELECT * into 表2 FROM 表1 2,这句只追加,不删除表2的数据 insert into 表1 select * f ...
- 42. oracle通过两张表的一个字段对应,update其中一张表的某个字段
update A a set a.A2 = (select b.B2 from B b where b.B1=a.A1) where exists (select 1 from B where B.B ...
- Sql 把Xml字符串转换成一张表
分享一个Sql技巧,把xml字符串转换成一个表格 DECLARE @IdHandel INT EXEC sp_xml_preparedocument @IdHandel OUTPUT, @Bar_Ip ...
随机推荐
- Java数据解析之XML
文章大纲 一.XML解析介绍二.Java中XML解析介绍三.XML解析实战四.项目源码下载 一.XML解析介绍 最基础的XML解析方式有DOM和SAX,DOM和SAX是与平台无关的官方解析方式 ...
- 数据结构学习java(一点五)链式顺序表(链表)
java中没有将指针暴露给用户(以前做过看过一篇文章写有java中是有指针的,只是被藏起来了),所以得使用引用的方式. 何为引用请看下面这篇文章(写的很不错,当然肯定比我写的好): https://w ...
- 用存储过程向数据库添加大量数据【mysql】
预分配ID的设计,需要先为数据库生成大量的数据.比如对用户ID有要求的系统,那么用户ID就要预先生成. 通过python,php,c/c++/c#,js等程序生成也是可以,但需要这些程序环境,而且单条 ...
- DVWA 黑客攻防实战(十五) 绕过内容安全策略 Content Security Policy (CSP) Bypass
看到标题,是否有点疑惑 CPS 是什么东东.简单介绍一下就是浏览器的安全策略,如果 标签,或者是服务器中返回 HTTP 头中有 Content-Security-Policy 标签 ,浏览器会根据标签 ...
- Puppeteer学习之小试牛刀
最近有了写文章的动力了,一方面是受到了很多前辈们的启示,另一方面也是为了记录下来更好地学以致用.闲言少叙,先说说Puppeteer是什么. Puppeteer是一个node库,提供了一些用来操作Chr ...
- PO,VO,TO,BO,DAO,POJO的解释
java的(PO,VO,TO,BO,DAO,POJO)解释 O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写.通俗点讲,就是将对象与关系数据库绑定 ...
- Go语言打造以太坊智能合约测试框架(level2)
传送门: 柏链项目学院 第二课 智能合约自动化编译 前期内容回顾 之前我们的介绍的是如何通过solc编译智能合约,并且调用智能合约,本节我们继续实践,将智能合约的代码自动化编译以及abi文件生成搞定. ...
- Jsp监听器
监听器: 监听器就是对内置对象的状态或者属性变化进行监听,并且做出反应的特殊的servlet,在web.xml文件中对监听器进行的配置. 内置对象有两种状态变化:产生.销毁,就是当产生内置对象的时候能 ...
- node.js、js读取excel、操作excel、创建excel之js-xlsx.js
node.js篇 第一步引入包 npm install xlsx -save 第二步使用 var xl =require('xlsx'); //workbook 对象,指的是整份 Excel 文档.我 ...
- SSZipArchive的使用详解和遇到的问题
https://blog.csdn.net/zhengang007/article/details/51019479 2016年03月30日 版权声明:本文为博主原创文章,转载请注明作者和原文链接. ...