详解SQL死锁检测的方法

sql server中的死锁是指进程之间互相永久阻塞的状态,下文就将为您介绍如何检测sql server死锁,希望对您有所帮助。

sql server中的死锁是指进程之间互相永久阻塞的状态,下文就将为您介绍如何检测sql server死锁,希望对您有所帮助。

死锁(deadlock)指进程之间互相永久阻塞的状态,SQL可以检测到死锁,并选择终止其中一个事务以干预sql server死锁状态。

第一步:首先创建两个测试表,表goods_sort和goods

表goods_sort:创建并写入测试数据

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

IF EXISTS(SELECT name FROM sysobjects WHERE name='goods_sort' AND xtype='U')

DROP TABLE dbo.goods_sort

–创建商品分类表

CREATE TABLE dbo.goods_sort(

iSortID int NOT NULL

CONSTRAINT PK_iSortID PRIMARY KEY

IDENTITY(1001,1),

sSortName NVARCHAR(20) NOT NULL

)

GO

INSERT INTO dbo.goods_sort VALUES('服饰')

INSERT INTO dbo.goods_sort VALUES('女包')

INSERT INTO dbo.goods_sort VALUES('鞋子')

INSERT INTO dbo.goods_sort VALUES('首饰')

INSERT INTO dbo.goods_sort VALUES('美容')

GO

表goods:创建并写入测试数据

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

IF EXISTS(SELECT name FROM sysobjects WHERE name='goods' AND xtype='U')

DROP TABLE dbo.goods;

–创建商品表

CREATE TABLE dbo.goods(

iID int NOT NULL

CONSTRAINT PK_iID PRIMARY KEY

IDENTITY(1,1),

iGoodsID varchar(20) NOT NULL,

sGoodsName nvarchar(100) NOT NULL,

iGoodTotal int NOT NULL

CONSTRAINT DF_iGoodTotal DEFAULT(0),

iPrice int NOT NULL

CONSTRAINT DF_iPrice DEFAULT(0),

iPriceTotal int NOT NULL,

iSortID int NOT NULL,

tAddDate smalldatetime NOT NULL

CONSTRAINT DF_tAddDate DEFAULT getdate()

)

GO

INSERT INTO dbo.goods

(iGoodsID,sGoodsName,iGoodTotal,iPrice,iPriceTotal,iSortID)

VALUES('YR6001','瘦身羽绒服',20,200,4000,1001)

INSERT INTO dbo.goods

(iGoodsID,sGoodsName,iGoodTotal,iPrice,iPriceTotal,iSortID)

VALUES('YR6002','加厚羽绒服',20,300,6000,1001)

INSERT INTO dbo.goods

(iGoodsID,sGoodsName,iGoodTotal,iPrice,iPriceTotal,iSortID)

VALUES('BB7001','小黄牛皮马鞍包',30,100,3000,1002)

INSERT INTO dbo.goods

(iGoodsID,sGoodsName,iGoodTotal,iPrice,iPriceTotal,iSortID)

VALUES('BB7002','十字绣流苏包',50,150,7500,1002)

GO

第二步:创建两个会产生死锁的事务

事务1:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

SET NOCOUNT ON;

SET XACT_ABORT ON;

GO

–使用TRY-CATCH,使代码发生错误也继续运行

BEGIN TRY

BEGIN TRAN

UPDATE dbo.goods_sort SET sSortName='女鞋' WHERE iSortID=1003;

WAITFOR DELAY '00:00:05';

UPDATE dbo.goods SET sGoodsName='胖子羽绒服' WHERE iID=2;

COMMIT TRAN

END TRY

BEGIN CATCH

IF (XACT_STATE()=-1)

ROLLBACK TRAN;

–ERROR_NUMBER()值为1205则表示发生了死锁

IF (ERROR_NUMBER() = 1205)

PRINT '事务1发生了死锁'

–写SQL Server日志或者返回错误给应用程序

END CATCH

SELECT iID,sGoodsName FROM dbo.goods WHERE iID=2;

SELECT iSortID,sSortName FROM dbo.goods_sort WHERE iSortID=1003;

GO

事务2:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

SET NOCOUNT ON;

SET XACT_ABORT ON;

GO

–使用TRY-CATCH,使代码发生错误也继续运行

BEGIN TRY

BEGIN TRAN

UPDATE dbo.goods SET sGoodsName='瘦子羽绒服' WHERE iID=2;

WAITFOR DELAY '00:00:05';

UPDATE dbo.goods_sort SET sSortName='男鞋' WHERE iSortID=1003;

COMMIT TRAN

END TRY

BEGIN CATCH

IF (XACT_STATE()=-1)

ROLLBACK TRAN;

–ERROR_NUMBER()值为1205则表示发生了死锁

IF (ERROR_NUMBER() = 1205)

PRINT '事务2发生了死锁'

–写SQL Server日志或者返回错误给应用程序

END CATCH

SELECT iID,sGoodsName FROM dbo.goods WHERE iID=2;

SELECT iSortID,sSortName FROM dbo.goods_sort WHERE iSortID=1003;

GO

然后运行事务1,接着马上运行事务2,这种情况下某一个事务会提示发生了死锁,修改不成功。另外一个事务则完成。

第一点:使用TRY.CATCH让产生异常的事务能继续完成后面的代码。

第二点:使用WAITFOR DELAY产生造成死锁的发生环境。

第三点:使用ERROR_NUMBER()来判断是否发生事务。

第四点:发生死锁,写SQL Server日志或者返回应用程序去写日志。便于检查日志的时候发现存在死锁并做相应的修改。

以上内容给大家介绍了SQL死锁检测的方法,希望大家喜欢。

版权声明:本文(即:原文链接:https://www.qin1qin.com/catagory/26781/)内容由互联网用户自发投稿贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 630367839@qq.com 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年 9月 28日 8:21:22
下一篇 2022年 9月 28日 8:21:28

软件定制开发公司

相关阅读

发表回复

登录后才能评论
通知:禁止投稿所有关于虚拟货币,币圈类相关文章,发现立即永久封锁账户ID!