sql server中的死鎖是指進(jìn)程之間互相永久阻塞的狀態(tài),下文就將為您介紹如何檢測sql server死鎖,希望對您有所幫助。
死鎖(deadlock)指進(jìn)程之間互相永久阻塞的狀態(tài),SQL可以檢測到死鎖,并選擇終止其中一個事務(wù)以干預(yù)sql server死鎖狀態(tài)。
第一步:首先創(chuàng)建兩個測試表,表goods_sort和goods
表goods_sort:創(chuàng)建并寫入測試數(shù)據(jù)
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 --創(chuàng)建商品分類表 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:創(chuàng)建并寫入測試數(shù)據(jù)
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; --創(chuàng)建商品表 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 |
第二步:創(chuàng)建兩個會產(chǎn)生死鎖的事務(wù)
事務(wù)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,使代碼發(fā)生錯誤也繼續(xù)運(yùn)行 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則表示發(fā)生了死鎖 IF (ERROR_NUMBER() = 1205) PRINT '事務(wù)1發(fā)生了死鎖' --寫SQL Server日志或者返回錯誤給應(yīng)用程序 END CATCH SELECT iID,sGoodsName FROM dbo.goods WHERE iID=2; SELECT iSortID,sSortName FROM dbo.goods_sort WHERE iSortID=1003; GO |
事務(wù)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,使代碼發(fā)生錯誤也繼續(xù)運(yùn)行 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則表示發(fā)生了死鎖 IF (ERROR_NUMBER() = 1205) PRINT '事務(wù)2發(fā)生了死鎖' --寫SQL Server日志或者返回錯誤給應(yīng)用程序 END CATCH SELECT iID,sGoodsName FROM dbo.goods WHERE iID=2; SELECT iSortID,sSortName FROM dbo.goods_sort WHERE iSortID=1003; GO |
然后運(yùn)行事務(wù)1,接著馬上運(yùn)行事務(wù)2,這種情況下某一個事務(wù)會提示發(fā)生了死鎖,修改不成功。另外一個事務(wù)則完成。
第一點(diǎn):使用TRY.CATCH讓產(chǎn)生異常的事務(wù)能繼續(xù)完成后面的代碼。
第二點(diǎn):使用WAITFOR DELAY產(chǎn)生造成死鎖的發(fā)生環(huán)境。
第三點(diǎn):使用ERROR_NUMBER()來判斷是否發(fā)生事務(wù)。
第四點(diǎn):發(fā)生死鎖,寫SQL Server日志或者返回應(yīng)用程序去寫日志。便于檢查日志的時候發(fā)現(xiàn)存在死鎖并做相應(yīng)的修改。
以上內(nèi)容給大家介紹了SQL死鎖檢測的方法,希望大家喜歡。