SQLSERVER死锁该如何深度分析
这篇文章将为大家详细讲解有关SQL SERVER死锁该如何深度分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
创新互联公司是一家集网站建设,明溪企业网站建设,明溪品牌网站建设,网站定制,明溪网站建设报价,网络营销,网络优化,明溪网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
说道SQL SERVER ,其实这个数据库在企业中是广泛使用的,这就必须提到为什么企业广泛使用SQL SERVER ,.NET VS JAVA ,在开发中我们目前有两大阵营,.NET 阵营和 JAVA 阵营,而一般来说使用.NET 开发是很愿意把 SQL SERVER 作为首选数据库的, 尤其是在中小型企业中,开发快,出色的性能,以及各种漂亮的图形化,让开发和管理,变得很简单,在讲求效率的今天,企业中还是有一大部分使用.NET 及 SQL SERVER 来满足企业的各种需求。
今天想说的是SQL SERVER 中程序员,DBA ,所有人都不愿意看见的死锁,DEAD LOCK。 出现这个情况,说明我们的整个系统在设计,以及硬件方面都可能存在一些,问题。所以我们必须要搞清楚死锁为什么会形成。
为了让说明变得简单,我这边需要创建一些表
CREATE TABLE Countrys
(
CountryID INT NOT NULL IDENTITY(1, 1)
CONSTRAINT PK_Country PRIMARY KEY,
CountryName VARCHAR(100),
PopulationSize INT NOT NULL
)
CREATE TABLE Citys
(
CityID INT NOT NULL IDENTITY(1, 1)
CONSTRAINT PK_City PRIMARY KEY,
CountryID INT NOT NULL,
CityName VARCHAR(100) NOT NULL,
PopulationSize INT NOT NULL,
CountOfHospitals INT NOT NULL,
SomeProperty1 VARCHAR(100) NOT NULL,
SomeProperty2 VARCHAR(100) NOT NULL,
SomeProperty3 VARCHAR(100) NOT NULL,
SomeProperty4 VARCHAR(100) NOT NULL,
SomeProperty5 VARCHAR(100) NOT NULL,
SomeProperty6 VARCHAR(100) NOT NULL,
SomeProperty7 VARCHAR(100) NOT NULL,
SomeProperty8 VARCHAR(100) NOT NULL,
SomeProperty9 VARCHAR(100) NOT NULL,
SomeProperty10 VARCHAR(100) NOT NULL,
SomeProperty11 VARCHAR(100) NOT NULL,
SomeProperty12 VARCHAR(100) NOT NULL,
SomeProperty13 VARCHAR(100) NOT NULL,
SomeProperty14 VARCHAR(100) NOT NULL,
SomeProperty15 VARCHAR(100) NOT NULL,
SomeProperty16 VARCHAR(100) NOT NULL,
SomeProperty17 VARCHAR(100) NOT NULL,
SomeProperty18 VARCHAR(100) NOT NULL,
SomeProperty19 VARCHAR(100) NOT NULL,
SomeProperty20 VARCHAR(100) NOT NULL,
SomeProperty21 VARCHAR(100) NOT NULL,
SomeProperty22 VARCHAR(100) NOT NULL,
SomeProperty23 VARCHAR(100) NOT NULL,
SomeProperty24 VARCHAR(100) NOT NULL,
SomeProperty25 VARCHAR(100) NOT NULL,
SomeProperty26 VARCHAR(100) NOT NULL,
SomeProperty27 VARCHAR(100) NOT NULL,
SomeProperty28 VARCHAR(100) NOT NULL,
SomeProperty29 VARCHAR(100) NOT NULL,
SomeProperty30 VARCHAR(100) NOT NULL,
SomeProperty31 VARCHAR(100) NOT NULL,
SomeProperty32 VARCHAR(100) NOT NULL,
SomeProperty33 VARCHAR(100) NOT NULL,
SomeProperty34 VARCHAR(100) NOT NULL,
SomeProperty35 VARCHAR(100) NOT NULL,
SomeProperty36 VARCHAR(100) NOT NULL,
SomeProperty37 VARCHAR(100) NOT NULL,
SomeProperty38 VARCHAR(100) NOT NULL,
SomeProperty39 VARCHAR(100) NOT NULL,
SomeProperty40 VARCHAR(100) NOT NULL,
CONSTRAINT FK_Country
FOREIGN KEY (CountryID)
REFERENCES dbo.Country (CountryID)
)
GO
CREATE INDEX IDX_City_Not_Covering_Index
ON dbo.Citys (CountryID)
INCLUDE (CityName)
GO
________________________________________________________
下面就开始变魔术,请开3个REQUEST 窗口,以 1 , 2 ,3,来标记语句是在哪个窗口上执行的
1
2
1
2
到目前为止,还么有出现死锁,(死锁怎么看,可以通过 EXEVENT 或自身 查看死锁的脚本来看,后面会给出脚本,EXEVENT 这里就不介绍了,虽然比脚本好用多了)
1 在窗口以继续执行下面的脚本
INSERT INTO dbo.Citys
VALUES
(1, -- CountryID - int
'New York', -- CityName - varchar(100)
8538000, --As Google just said and that's cool!
1000, --From the ceiling
)
2 在窗口2 继续执行下面的脚本
INSERT INTO dbo.Citys
VALUES
(2, -- CountryID - int
'Delhi', -- CityName - varchar(100)
19980000, --As Google just said and that's cool!
2000, --From the ceiling
)
1 我们在窗口1 继续查询
2 我们在窗口2 也查询
然后魔术上演,在窗口2 出现死锁提示
EXEVENT 中也出现了死锁图示
估计有些SQL SERVER DBA 已经清晰的明白这里发生了什么,为什么会死锁? 如果已经明白了,那就真的么有必要往下看了。
————————————————————————————
死锁发生在给CITYS 表插入记录的时候,当插入CITYS 表 "NEW YORK“的时候,给这一行加了 X 锁,(行锁) ,当我在插入CITYS 表 “Delhi" 时,给Delhi 这一行(应该是第二行加上了X锁) 到目前为止,还算相安无事。
但我马上做了一个糟糕的操作,我查询了CITY 表,虽然我建立了索引,(这里买一个关子,好好想想,我还是用上面的操作,只需要改一个地方,就可以避免这次死锁,和查询的方式有关)
,这是就加上了 S 锁,而不巧的是,这个S锁也锁住了 "NEW YORK"和Delhi,然后就是触发死锁的发生最后一步,我查询 Delhi , 而这个查询也要给 "NEW YORK" 上一个 S 锁,好了,由于之前每行都有 X 锁,所以虽然行锁可以避免对本行的 S 锁产生等待,但不能对其他行避免等待,所以两次查询,变成了死锁,互相等待。(估计我说完了,有人已经晕了,画张图,马上就明白了)
看完图应该明白,为什么产生死锁,也明白本星期四某些故障的原因,和这个很类似,所以某些时候,并发害死人呀
其实要解决这个问题,也很简单,但又不简单,尤其在一个复杂的系统中,串行不出问题,不代表并行不会出现问题,大量的死锁就是这么“神奇”的出现。
最后,可以通过以下脚本来,查看某些死锁,或者锁授予的情况。
SELECT OBJECT_NAME(p.object_id) AS TableName,
dtl.resource_type,
dtl.resource_description,
--c.CityName AS Locked_Row,
--c.CityID AS Locked_Row_ID,
dtl.request_mode,
dtl.request_type,
dtl.request_status,
dtl.request_session_id,
dtl.request_owner_type,
dtl.request_owner_id
FROM sys.dm_tran_locks AS dtl
LEFT JOIN sys.partitions AS p
ON p.hobt_id = dtl.resource_associated_entity_id
关于SQL SERVER死锁该如何深度分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
分享标题:SQLSERVER死锁该如何深度分析
本文链接:http://scjbc.cn/article/jpesio.html