热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

1--死锁案例分析P33323--先开启监视死锁的开关1222,让SQL遇到死锁时,在errorlog里打印出4--死锁的详细内容56DBCCTRACEON(1222,-1)78-
 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]=480951955104 SELECT * FROM [dbo].[Employee_Demo_Heap] WITH (NOLOCK)
105 WHERE [NationalIDNumber]=480951955106 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]=+480951955121 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]=480951955143 SELECT * FROM [dbo].[Employee_Demo_Heap] WITH (PAGLOCK)
144 WHERE [NationalIDNumber]=480951955145 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]=480951955170 SELECT * FROM [dbo].[Employee_Demo_Heap]
171 WHERE [NationalIDNumber]=480951955172 COMMIT TRAN
173 END
174 
175 -----------------------------------总结------------------------------------------------------
176 --分析和解决死锁的时候,思路要开阔一点,从设计着手

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


推荐阅读
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
author-avatar
影帝
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有