牛人笔记----(死锁案例分析)

 1 --死锁案例分析 P333
  2
  3 --先开启监视死锁的开关1222,让SQL遇到死锁时,在errorlog里打印出
  4 --死锁的详细内容
  5
  6 DBCC TRACEON(1222,-1)
  7
  8 --这里使用范例表dbo.Employee_Demo_Heap
  9
 10 --这张表在EmployeeID和ManagerID字段上各有一个非聚集索引,但是没有聚集索引
 11
 12
 13 --现在用下面脚本来模拟出一个死锁来。在一个连接里,运行下面语句,反复开启
 14 --事务。在这个事务里,先修改一条NationalIDNumber=‘480951955‘的记录,然后
 15 --把他查询出来。完成以后,再提交事务
 16
 17 USE [AdventureWorks]
 18 GO
 19 SET NOCOUNT ON
 20 GO
 21 WHILE 1=1
 22 BEGIN
 23 BEGIN TRAN
 24 UPDATE [dbo].[Employee_Demo_Heap]
 25 SET [BirthDate] =GETDATE()
 26 WHERE [NationalIDNumber]=‘480951955‘
 27 SELECT * FROM [dbo].[Employee_Demo_Heap]
 28 WHERE [NationalIDNumber]=‘480951955‘
 29 COMMIT TRAN
 30 END
 31
 32
 33 --在另一个连接里也运行这些语句,唯一差别是这次修改和查询是另一条
 34 --NationalIDNumber=‘407505660‘的记录
 35
 36 USE [AdventureWorks]
 37 GO
 38 SET NOCOUNT ON
 39 --当 SET NOCOUNT 为 ON 时,不返回计数(表示受 Transact-SQL 语句影响的行数)。当 SET NOCOUNT 为 OFF 时,返回计数。如果存储过程中包含的一些语句并不返回许多实际的数据,则该设置由于大量减少了网络流量,因此可显著提高性能。
 40 GO
 41 WHILE 1=1
 42 BEGIN
 43 BEGIN TRAN
 44 UPDATE dbo.[Employee_Demo_Heap]
 45 SET [BirthDate]=GETDATE()
 46 WHERE [NationalIDNumber]=‘407505660‘
 47 SELECT * FROM [dbo].[Employee_Demo_Heap]
 48 WHERE [NationalIDNumber]=‘407505660‘
 49 COMMIT TRAN
 50 END
 51
 52
 53 --两条语句一起运行,无须多长时间就会有其中一个连接遇到死锁的错误
 54
 55 --消息1205,级别13,状态45,第4行
 56 --事务(进程ID 54)与另一个进程被死锁在锁资源上,并且已被选作死锁牺牲品
 57 --请重新运行该事务
 58
 59 DBCC TRACEON(3604)
 60 DBCC PAGE(9,1,6685,3)
 61
 62 --常见的四种解决死锁的方法
 63 --1、调整索引,以调整执行计划,减少锁的申请数目,从而消除死锁
 64 --如果死锁的双方不会申请对方要申请的锁,那么死锁也不会发生。如果
 65 --数据库设计者能够引导SQL使用seek的执行计划,只读取要返回的数据,
 66 --那么申请的锁数量会大大降低,死锁的几率也会减少
 67
 68 --上面的情况可以在NationalIDNumber字段上加一个索引,SQL可以更快地
 69 --找到数据,而无须申请这麽多锁。执行计划都变成seek类型
 70 USE [AdventureWorks]
 71 CREATE NONCLUSTERED INDEX NationalIDNumber ON [Employee_Demo_Heap]([NationalIDNumber] ASC)
 72
 73 --注意:加索引的时候,如果数据库在运行环境,由于某些查询还在查询数据表那么索引不会添加成功
 74 --除非,预先在建立好表结构的时候就加上索引,或者在晚上停机时间加索引
 75
 76 --这是一种比较好的方法,能够提高语句执行效率,又消除死锁。所以应该尽可能地使用
 77 --但是他也有局限性,对语句和数据库有下面两个要求:
 78
 79 --(1)死锁双方处理的数据本身没有交叉
 80 --如果双方都要修改或返回同样的数据,那么再优化索引,可能也没有用处
 81
 82 --(2)DBA要有权力在数据库里调整索引设计
 83
 84 --有些数据库是跟着应用来的,DBA必须征得应用开发团队的同意,才能修改数据库设计
 85 --调整之前,要考虑到修改可能会带来的负面作用。不要这个死锁消除了,其他地方
 86 --又出现新的死锁和阻塞
 87
 88 --当这个方法不可用的时候,可以考虑下面三个比较粗鲁的方法
 89
 90 --2、使用“nolock”参数,让select 语句不要申请S锁,减少锁的申请数目,从而
 91 --消除死锁
 92 --很多死锁发生在S锁上面,我们可以通过在语句里加“nolock”参数的方法,让
 93 --select语句不要去申请S锁,死锁自然也会消失
 94 USE [AdventureWorks]
 95 GO
 96 SET NOCOUNT ON
 97 GO
 98 WHILE 1=1
 99 BEGIN
100 BEGIN TRAN
101 UPDATE [dbo].[Employee_Demo_Heap]
102 SET [BirthDate] =GETDATE()
103 WHERE [NationalIDNumber]=‘480951955‘
104 SELECT * FROM [dbo].[Employee_Demo_Heap] WITH (NOLOCK)
105 WHERE [NationalIDNumber]=‘480951955‘
106 COMMIT TRAN
107 END
108
109 --这个方法解决死锁可以说是立竿见影,所以很多用户很喜欢使用他
110 --但是缺点很明显
111 --with (nolock)这个参数意味着,select语句将能接收脏读,这是SQL
112 --支持的最低一级事务隔离级别。用户要能够理解他的副作用,并且能够
113 --接受,才能使用
114 --这种方法只能解决S锁参与的死锁问题,如果死锁发生在U锁或X锁上,with (nolock)
115 --没有帮助
116 --这个方法要去修改语句本身。如果语句是由应用程序动态生成,而不是写在SQL
117 --的存储过程里,要应用开发人员才能够修改
118 DECLARE @a NVARCHAR(4000)
119 SET @a=‘SELECT * FROM [dbo].[Employee_Demo_Heap] WITH (NOLOCK)
120 WHERE [NationalIDNumber]=‘+‘480951955‘
121 EXEC(@a)
122
123 --3、升级锁粒度,将死锁转化为一个阻塞问题
124 --死锁产生的原因是双方都申请到了一个资源,同时又要申请对方的资源。
125 --如果一方一个资源都没有申请到,那么发生的就是阻塞,而不是死锁
126 --从这个角度讲,如果能想办法让一方被另一方阻塞住,什么资源都申请不到
127 --那死锁就不会发生
128
129 --从上面的例子里,死锁发生在同一个page上的不同rid上。如果语句直接申请Page
130 --级别的锁,同时就只能有一个人得到锁资源,而另一个人会被阻塞住。因此,
131 --使用pagelock这个参数,也能解决这里的死锁问题。
132
133 USE [AdventureWorks]
134 GO
135 SET NOCOUNT ON
136 GO
137 WHILE 1=1
138 BEGIN
139 BEGIN TRAN
140 UPDATE [dbo].[Employee_Demo_Heap] WITH (PAGLOCK)
141 SET [BirthDate] =GETDATE()
142 WHERE [NationalIDNumber]=‘480951955‘
143 SELECT * FROM [dbo].[Employee_Demo_Heap] WITH (PAGLOCK)
144 WHERE [NationalIDNumber]=‘480951955‘
145 COMMIT TRAN
146 END
147
148 --这种方法虽然不会降低事务隔离级别,但是语句更容易被阻塞住,最终
149 --的并发度难免受到影响。因此实际上也是一种粗鲁的方法。没有第一种
150 --通过加索引的方法那么精细。如果能用第一种方法,还是使用第一种方法
151 --比较负责任
152
153 --4、使用快照隔离级别
154 --由于这个死锁里有S锁参与,这里把事务隔离级别从默认的已提交读
155 --改成快照,对缓解这个死锁也会有很好帮助。在语句的开头加上
156 --这句话就行
157 SET TRANSACTION ISOLATION LEVEL SNAPSHOT
158 GO
159
160 USE [AdventureWorks]
161 GO
162 SET NOCOUNT ON
163 GO
164 WHILE 1=1
165 BEGIN
166 BEGIN TRAN
167 UPDATE [dbo].[Employee_Demo_Heap]
168 SET [BirthDate] =GETDATE()
169 WHERE [NationalIDNumber]=‘480951955‘
170 SELECT * FROM [dbo].[Employee_Demo_Heap]
171 WHERE [NationalIDNumber]=‘480951955‘
172 COMMIT TRAN
173 END
174
175 -----------------------------------总结------------------------------------------------------
176 --分析和解决死锁的时候,思路要开阔一点,从设计着手
时间: 2024-11-13 02:12:17

牛人笔记----(死锁案例分析)的相关文章

牛人笔记----(死锁问题定位与解决方法)

1 --死锁问题定位与解决方法 2 3 --为了解决死锁问题,SQLSERVER数据库引擎死锁监视器会定期检查陷入死锁的任务 4 --如果监视器检测到这种依赖循环关系,会选择其中一个任务作为牺牲品,然后 5 --终止其事务并提示错误.这就是用户会遇到的死锁错误 6 7 --可以发生死锁的资源 8 --需要说明的是,死锁不是只发生在锁资源上,以下类型的资源都可能会造成阻塞,并 9 --最终导致死锁 10 11 --1.锁:例如:页,行,元数据和应用程序上的锁 12 --2.工作线程:如果排队等待线

MySQL批量更新死锁案例分析--转载

问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下: [java] view plaincopyprint? com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction at sun.reflect.GeneratedConstructorAccessor24

MySQL死锁案例分析与解决方案

现象: 数据库查询: SQL语句分析: mysql. 并发delete同一行记录,偶发死锁. delete from x_table where id=? 死锁分析: mysql的事务支持与存储引擎有关,MyISAM不支持事务,INNODB支持事务,更新时采用的是行级锁.这里采用的是INNODB做存储引擎,意味着会将update语句做为一个事务来处理.前面提到行级锁必须建立在索引的基础,这条更新语句用到了索引idx_1,所以这里肯定会加上行级锁. 行级锁并不是直接锁记录,而是锁索引,如果一条SQ

MySql一个生产死锁案例分析

接到上级一个生产环境MySQL死锁日志信息文件,需要找出原因并解决问题.我将死锁日志部分贴出如下: 在mysql中使用命令:SHOW ENGINE INNODB STATUS;总能获取到最近一些问题信息,通过搜索deadlock 关键字即可找到死锁的相关日志信息. 2019-09-25 13:28:25 7fc0301ca700InnoDB: transactions deadlock detected, dumping detailed information. 2019-09-25 13:2

一次Mysql下批量更新造成的死锁案例分析

最近,公司现网的业务中出现上图所示的死锁异常,沿着问题分析,发现这个问题涉及很多数据库的基础知识. 背景: 使用数据库:Mysql 涉及表格:t_invest 数据库隔离级别:可重复读(Repeatable Read) 死锁场景:saveRepaymentInfo事务的A()方法对t_invest表执行如下update操作: <update id = "A" parameterType = "java.util.List"> <foreach co

牛人与新手的区别

1.牛人就是越来越觉得自己不牛的人:生手就是觉得自己越来越牛的人. 2.牛人就是越来越感觉不会的东西越来越多的人:生手就是觉得不会的东西越来越少的人. 3.牛人就是代码写得越来越简单的人:生手就是代码写得越来越复杂的人. 4.牛人就是动手之前总是不知道如何动手的人:生手就是动手之前根本不用考虑如何动手的人. 5.牛人就是有时候根本都不知道自己在用范式的人:生手就是要么不知道范式,要么千方百计使用范式的人. 6.牛人是全生命周期都在重构的人:生手就是到不得已的时候才想起重构的人. 7.牛人的代码就

《大型网站技术架构:核心原理与案例分析》笔记

目录 · 大型网站软件系统的特点 · 大型网站架构演化发展历程 · 初始阶段的网站架构 · 需求/解决问题 · 架构 · 应用服务和数据服务分离 · 需求/解决问题 · 架构 · 使用缓存改善网站性能 · 需求/解决问题 · 架构 · 使用应用服务器集群改善网站的并发处理能力 · 需求/解决问题 · 架构 · 数据库读写分离 · 需求/解决问题 · 架构 · 使用反向代理和CDN加速网站响应 · 需求/解决问题 · 架构 · 使用分布式文件系统和分布式数据库系统 · 需求/解决问题 · 架构 ·

作业04之《大型网站技术架构:核心原理与案例分析》阅读笔记

在这一节课上,我们学习了系统质量属性其中的可用性和易用性.那么质量属性是什么呢,质量属性是高于对系统功能(即对系统能力.服务和行为)的基本的要求的.系统质量属性讲重点放在了可用性.可修改性.性能.安全性.可测试性和易用性.从设计师方面,系统质量属性一般存在三个问题:(1)为属性提供的定义并不是可操作的.(2)重点通常是一个特定的方面属于哪个质量属性.(3)每个属性团队都开发了其自己的词汇. 今天我们就根据<大型网站技术架构:核心原理与案例分析>将重点放在可用性和易用性的学习讨论上以及将其方法和

《大型网站技术架构:核心原理与案例分析》笔记03

<大型网站技术架构:核心原理与案例分析>笔记01 1.大型网站核心架构要素. 架构:"最高层次的规划,难以改变的决定."从这个角度而言,人生规划也是一种架构.选什么学校.学什么专业.进什么公司.找什么对象,过什么样的生活,都是自己人生的架构. 软件架构:"有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计." 五大要素:性能.可用性.伸缩性.扩展性和安全性. 2.性能测试指标: 响应时间:指应用执行一个操作需要的时间,包括从发出请求开始