SQLSERVER死锁详解

看了网上很多关于死锁的的博客,大家通常介绍死锁的原理,本人也写一个详细的分析。当然,是关于SQLSERVER的死锁。

使用SQL Profiler抓取死锁事件

2、选择选项卡:事件选择,勾选右下角的显示所有事件,找到Locks事件,勾选上Deadlock graph。

3、再选择第三个选项卡:事件提取设置,勾上死锁XML,弹出文件保存路径,输入文件名即可。

4、以上设置,出现死锁时会保存到死锁XML文件中,经操作发现只保存了最后一个死锁图,如果死锁比较多,需要使用SQL Profiler逐个保存。

5、死锁XML文件默认后缀为.xdl,双击直接打开就会使用SSMS打开,仅仅只能看到很基础的信息。如下:

这种图示并不能详细的说明问题。我们可以采取另外一种办法,左键选择死锁XML文件,右键选择打开方式:文本编辑器。整个死锁的内容就一目了然了,如下:

红色的框框,是我标注出来的,我主要对黑色框框里面的做详细说明,其实有很多了解死锁的朋友看了之后基本已经明白了。

1、  每一个死锁XML文件有一个根节点:deadlock-list。

2、  在根节点下,有一个节点deadlock victim="process59bcbc8",其中victim值为死锁的编号,如果打开的一个SQL Profiler下出现多个死锁,那么它们的编号是一致的,只有不同的SQL Profiler追踪的死锁编号才会有不同。此外该值为牺牲的进程ID号,与别的ID号区分,这个在之后会详细介绍。

3、  在deadlock victim节点下有两个节点,process-list,resource-list。process-list节点主要解释死锁的一些相关信息。resource-list节点解释锁的授予情况。

4、  process-list节点,一般有两个process节点,每个节点代表着一个死锁中的一个进程,如果多个进程造成的死锁,那就会出现多个process节点。我们先看第一个process节点,这个节点根据之前的图片可以看出,是被牺牲的进程。

1)属性id="process7a9a988",这个是被牺牲的进程ID号,在文件中我们可以看到两个process节点的ID号不同。另一个节点的id属性为id="process7abee08"

2) 属性waitresource=”PAGE: 7:1:8459005”,Page代表这是一个页锁,这个页面出现在数据库ID=7,文件ID=1,页面ID=8459005的位置。另一个Procee节点下的waitresource="PAGE: 7:1:7861369"。

3) 属性transactionname ="SELECT",表示事务类型,SELECT表示这是一个查询事务,可以跟另一个Procee节点下的transactionname属性进行比较,transactionname="UPDATE"

4) 属性lockMode="S",锁的模式为共享锁。另一个process节点的锁模式lockMode="IX"为意向排他锁。

5) 属性status="suspended",锁的状态。另一个process节点的status="suspended"。

6) 属性hostname="999VISTA"指操作这个事务的电脑名。另一个process节点的hostname="jack"

7) 属性loginname="sa"指登录数据库的SQL账户。另一个process节点的loginname="aaa"。

8) 属性isolationlevel="read committed (2)"指事务隔离级别。

9) 节点executionStack,在它之下有两个frame节点,第一个节点中间的文本是执行语句。第二个节点,没弄明白什么意思。

10) 节点inputbuf,这个节点中间的文本也是执行语句,与executionStack节点下第一个frame节点的文本相同,推测executionStack节点下第二个节点是不是在一个执行进程中其他的SQL语句??

5、  resource-list节点。这个节点下有两个pagelock节点,分别代表两个进程各自持有的页锁。如果有多个页锁,是不是会有多个pagelock节点?或者是表锁那会是什么节点??

1)  第一个pagelock节点,fileid="1" pageid="8459005" dbid="7",这个跟process-list节点下第一个process节点的属性waitresource=”PAGE: 7:1:8459005”意思相同。objectname=” 表名",这个是表名,具体格式:db_name.schema_name.Table_name。

2)  pagelock节点下有多个owner-list节点,这个是每一个进程就有一个节点,该示例中由于死锁是由两个进程造成,只有两个节点。

3)  owner-list节点有一个owner,这个代表着锁的授予情况,推测:如果持有多个锁,可能有多个节点。

4)  owner节点:id="process7abee08" mode="IX",id表示进程ID,mode表示锁类型。

5)  pagelock节点下有多个waiter-list节点,这个节点是与owner-list节点一一对应。

6)  waiter-list节点有一个waiter节点,这个代表着锁的授予情况,推测:如果持有多个锁,可能有多个节点。

7)  waiter节点:id="process7a9a988" mode="S" requestType="wait",id表示进程ID,mode表示锁类型,requestType表示等待授予中。

8)  通过以上的介绍,我们可以了解到:

进程process7a9a988先拥有了Page:7:1:7861369的共享锁S,这个时候,它请求获取Page:7:1:8459005的共享锁S,与此同时,process7abee08先拥有了Page:7:1:8459005的意向排他锁IX,又请求获取Page:7:1:7861369的意向排他锁,这样,两个进程相互阻塞造成了死锁的原因。我对此结合数据库表结构分析,发现该表的每行字段都有6880个字符,也就是说,一行就占用了一个页面,同时,进程process7a9a988使用的是LINQ查询,由于LINQ导致这个查询居然不走聚集索引,先走AccountID字段的索引然后在嵌套循环主键索引CaseID,是死锁的原因之一。

以上就是本人对死锁的见解,如有异议,欢迎提出讨论。

SQLSERVER死锁详解

时间: 2024-10-20 19:36:58

SQLSERVER死锁详解的相关文章

“全栈2019”Java多线程第十九章:死锁详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第十九章:死锁详解 下一章 "全栈2019"Java多线程第二十章:同步方法产生死锁的例子 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组&q

SQLServer游标详解

一.游标概念 我们知道,关系数据库所有的关系运算其实是集合与集合的运算,它的输入是集合输出同样是集合,有时需要对结果集逐行进行处理,这时就需要用到游标.我们对游标的使用一本遵循"五步法":声明游标->打开游标->读取数据->关闭游标->删除游标.以下就从这五步对游标的使用进行说明,并给出具体实例. 二."五步法"讲解 1.声明游标(DECLARE CURSOR) (1) DECLARE CURSOR 既接受基于 ISO 标准的语法,也接受使用

SQLServer 游标详解

一.用到的数据 CREATE TABLE [dbo].[XSB]( [学号] [char](6) NOT NULL, [姓名] [char](8) NOT NULL, [性别] [bit] NULL, [出生时间] [date] NULL, [专业] [char](12) NULL, [总学分] [int] NULL, [备注] [varchar](500) NULL, PRIMARY KEY CLUSTERED ( [学号] ASC )WITH (PAD_INDEX = OFF, STATIS

sqlserver锁机制详解(sqlserver查看锁)

简介 在SQL Server中,每一个查询都会找到最短路径实现自己的目标.如果数据库只接受一个连接一次只执行一个查询.那么查询当然是要多快好省的完成工作.但对于 大多数数据库来说是需要同时处理多个查询的.这些查询并不会像绅士那样排队等待执行,而是会找最短的路径执行.因此,就像十字路口需要一个红绿灯那 样,SQL Server也需要一个红绿灯来告诉查询:什么时候走,什么时候不可以走.这个红绿灯就是锁. 图1.查询可不会像绅士们那样按照次序进行排队 为什么需要锁 在开始谈锁之前,首先要简单了解一下事

使用系统存储过程来监控SQLServer进程和会话详解

 承接上文,本文讲述如何使用系统存储过程来监控系统. SQLServer同样也提供了一系列系统存储过程用于监控SQLServer,获取当前进程.会话.请求以及锁定的详细信息.本文将演示系统存储过程来实现这些监控. 情景: 有时候你会发现应用程序突然变得很慢,经常需要等待数据库响应,此时你需要快速查看是否请求被阻塞或者挂起. 准备工作: 在本文中,将使用以下存储过程来获取当前进程的信息: Sp_who Sp_who2 步骤: 1.  打开SSMS连到SQLServer实例并打开新查询窗口. 2

【DataBase】sqlserver字段类型详解

bit    整型 bit数据类型是整型,其值只能是0.1或空值.这种数据类型用于存储只有两种可能值的数据,如Yes 或No.True 或False .On 或Off. 注意:很省空间的一种数据类型,如果能够满足需求应该尽量多用. tinyint   整型 tinyint 数据类型能存储从0到255 之间的整数.它在你只打算存储有限数目的数值时很有用.这种数据类型在数据库中占用1 个字节. 注意:如果bit类型太单调不能满足您的需求,您可以考虑用tinyint类型,因为这个类型相对也是比较安全的

SQLSERVER存储过程语法详解

SQL SERVER存储过程语法: Create PROC [ EDURE ] procedure_name [ ; number ]     [ { @parameter data_type }         [ VARYING ] [ = default ] [ OUTPUT ]     ] [ ,...n ] [ WITH     { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ] [ FOR REPLICATION ] AS sq

SQLServer 服务器角色和数据库角色权限详解

SQLServer中服务器角色和数据库角色权限详解 转自:http://blog.csdn.net/e_online/article/details/4597957 角色 当几个用户需要在某个特定的数据库中执行类似的动作时(这里没有相应的Windows用户组),就可以向该数据库中添加一个角色(role).数据库角色指定了可以访问相同数据库对象的一组数据库用户.数据库角色的成员可以分为如下几类:Windows用户组或用户账户SQL Server登录其他角色SQL Server的安全体系结构中包括了

SQLServer中服务器角色和数据库角色权限详解

SQLServer中服务器角色和数据库角色权限详解 by e-online 26. 九月 2009 18:55 coming from http://blog.csdn.net/e_online/article/details/4597957 角色 当几个用户需要在某个特定的数据库中执行类似的动作时(这里没有相应的Windows用户组),就可以向该数据库中添加一个角色(role).数据库角色指定了可以访问相同数据库对象的一组数据库用户. 数据库角色的成员可以分为如下几类: Windows用户组或