温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

SQL SERVER死锁该如何深度分析

发布时间:2021-12-28 14:28:53 来源:亿速云 阅读:105 作者:柒染 栏目:大数据

这篇文章将为大家详细讲解有关SQL SERVER死锁该如何深度分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

说道SQL SERVER ,其实这个数据库在企业中是广泛使用的,这就必须提到为什么企业广泛使用SQL SERVER ,.NET  VS  JAVA ,在开发中我们目前有两大阵营,.NET 阵营和 JAVA 阵营,而一般来说使用.NET 开发是很愿意把 SQL SERVER 作为首选数据库的, 尤其是在中小型企业中,开发快,出色的性能,以及各种漂亮的图形化,让开发和管理,变得很简单,在讲求效率的今天,企业中还是有一大部分使用.NET 及 SQL SERVER 来满足企业的各种需求。

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

SQL SERVER死锁该如何深度分析

2

SQL SERVER死锁该如何深度分析

1

SQL SERVER死锁该如何深度分析

2

SQL SERVER死锁该如何深度分析

到目前为止,还么有出现死锁,(死锁怎么看,可以通过 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  继续查询

SQL SERVER死锁该如何深度分析

2 我们在窗口2 也查询

SQL SERVER死锁该如何深度分析

然后魔术上演,在窗口2 出现死锁提示

SQL SERVER死锁该如何深度分析

EXEVENT 中也出现了死锁图示

SQL SERVER死锁该如何深度分析

估计有些SQL SERVER DBA 已经清晰的明白这里发生了什么,为什么会死锁? 如果已经明白了,那就真的么有必要往下看了。

————————————————————————————

死锁发生在给CITYS 表插入记录的时候,当插入CITYS 表  "NEW YORK“的时候,给这一行加了 X 锁,(行锁) ,当我在插入CITYS 表 “Delhi" 时,给Delhi 这一行(应该是第二行加上了X锁) 到目前为止,还算相安无事。

但我马上做了一个糟糕的操作,我查询了CITY 表,虽然我建立了索引,(这里买一个关子,好好想想,我还是用上面的操作,只需要改一个地方,就可以避免这次死锁,和查询的方式有关)

,这是就加上了 S 锁,而不巧的是,这个S锁也锁住了 "NEW YORK"和Delhi,然后就是触发死锁的发生最后一步,我查询 Delhi , 而这个查询也要给 "NEW YORK" 上一个 S 锁,好了,由于之前每行都有 X 锁,所以虽然行锁可以避免对本行的 S 锁产生等待,但不能对其他行避免等待,所以两次查询,变成了死锁,互相等待。(估计我说完了,有人已经晕了,画张图,马上就明白了)

SQL SERVER死锁该如何深度分析

看完图应该明白,为什么产生死锁,也明白本星期四某些故障的原因,和这个很类似,所以某些时候,并发害死人呀

其实要解决这个问题,也很简单,但又不简单,尤其在一个复杂的系统中,串行不出问题,不代表并行不会出现问题,大量的死锁就是这么“神奇”的出现。

最后,可以通过以下脚本来,查看某些死锁,或者锁授予的情况。

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死锁该如何深度分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI