抄录网址: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锁的时候,都不是整张表进行扫描的,而是直接就可以根据索引找到这条记录进行升级锁,所以,不会出现上面的死锁的问题。

最新文章

  1. MyCat源码分析系列之——SQL下发
  2. BaseAdapter的抽取
  3. spring事务手动回滚
  4. Failed to apply plugin [id 'com.android.application'] 和 Could not find com.android.tools.build:gradle:2.XX的最正确的解决方法
  5. Unity 5.3 安装完没有Android(安卓)或IOS Module(模块)?
  6. PYTHON seek()tell()语句
  7. net 页面跳转
  8. 非旋转Treap及可持久化[Merge,Split]
  9. Loadrunner:POP3协议录制收信,使用foxmail录制到的脚本为空
  10. vs2012布局问题
  11. IOS-tableView中的cellHeadView随着table滚动
  12. Yeoman入门之安装及环境配置
  13. 第四天 内置函数2 随机码 装饰器 迭代器、生成器 递归 冒泡算法 JSON
  14. zookeeper基本讲解及基本命令和配置 (转)
  15. 小笔记:Timer定时间隔时间操作
  16. HAL库详解
  17. Git的基本使用(github)
  18. Linux内核入门(六)—— __attribute__ 机制【转】
  19. PAC 自动代理
  20. python--selenium实用的自动生成测试HTML报告方法--HTMLTestRunner

热门文章

  1. centos7后台服务部署jar包
  2. c# 创建excel表头及内容
  3. RuntimeException和Exception区别
  4. 电脑开机后win系统运行异常慢,鼠标移动卡
  5. Bootstrap -- 插件: 提示工具、弹出框、 警告框消息
  6. 最新webstorm
  7. git tag 打标签
  8. Git clone远程目录443:Timed out 问题(go get)
  9. 华硕飞行堡垒fx50 安装ubuntu18.04
  10. e2e测试框架之Cypress