标签:
1,打开跟踪,写入日志
DBCC TRACEON (3605,1222,-1) –3605写入errorlog,1222死锁
DBCC TRACEON(1222,-1) /若在启动时,加-T 1222
同时,可开profile中的Deadlock graph跟踪,以图形化
2,分析安装目录下生成的日志
1)确定死锁的资源, 据对象不同查看方式不同。
DBCC TRACEON(3604)
死锁产生的前提:双方互占有了对方所需求的资源,若资源并不必要,可过滤掉。
资源不必要:1)扫描了对方的资源,扫描过的就会加锁,避免被扫描到,如加索引等。
3,死锁处理方法:
1)从性能出发,优化sql
2)从业务逻辑出发,看是否可去掉对死锁资料的关联。
3)若还是不能解决,死锁是正常情况,避免不了,但可避免输出1205错误信息给客户端,方法就是加上try catch,可以等一会儿再重新执行。
如:
/*避免死锁显示给客户端 */ DECLARE @retries INT ; SET @retries = 4 ; WHILE ( @retries > 0 ) BEGIN BEGIN TRY BEGIN TRANSACTION ; -- place sql code here SET @retries = 0 ; COMMIT TRANSACTION ; END TRY BEGIN CATCH -- Error is a deadlock IF ( ERROR_NUMBER() = 1205 ) SET @retries = @retries - 1 ; -- Error is not a deadlock ELSE BEGIN DECLARE @ErrorMessage NVARCHAR(4000) ; DECLARE @ErrorSeverity INT ; DECLARE @ErrorState INT ; SELECT @ErrorMessage = ERROR_MESSAGE() , @ErrorSeverity = ERROR_SEVERITY() , @ErrorState = ERROR_STATE() ; -- Re-Raise the Error that caused the problem RAISERROR (@ErrorMessage, -- Message text. @ErrorSeverity, -- Severity. @ErrorState -- State. ) ; SET @retries = 0 ; END IF XACT_STATE() <> 0 ROLLBACK TRANSACTION ; END CATCH ; END ; GO
/*死锁模拟 1,建立数据 2,连续两个事务 */ drop table Employee_Demo_Heap go SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [Employee_Demo_Heap]( [EmployeeID] [int] NOT NULL, [NationalIDNumber] [nvarchar](15) NOT NULL, [ContactID] [int] NOT NULL, [LoginID] [nvarchar](256) NOT NULL, [ManagerID] [int] NULL, [Title] [nvarchar](50) NOT NULL, [BirthDate] [datetime] NOT NULL, [MaritalStatus] [nchar](1) NOT NULL, [Gender] [nchar](1) NOT NULL, [HireDate] [datetime] NOT NULL, [ModifiedDate] [datetime] NOT NULL DEFAULT (getdate()), CONSTRAINT [PK_Employee_EmployeeID_Demo_Heap] PRIMARY KEY nonCLUSTERED ( [EmployeeID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE NONCLUSTERED INDEX [IX_Employee_ManagerID_Demo_Heap] ON [Employee_Demo_Heap] ( [ManagerID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO CREATE NONCLUSTERED INDEX [IX_Employee_ModifiedDate_Demo_Heap] ON [Employee_Demo_Heap] ( [ModifiedDate] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO insert into Employee_Demo_Heap select [EmployeeID] , [NationalIDNumber] , [ContactID] , [LoginID] , [ManagerID], [Title] , [BirthDate] , [MaritalStatus] , [Gender] , [HireDate] , [ModifiedDate] from HumanResources.Employee go 现在就用下面这组脚本模拟出一个死锁来。在一个连接里,运行下面的语句。反复开启事务。在这个事务里,先修改一条NationalIDNumber=‘480951955’的记录,然后再把它查询出来。做完以后,提交事务。 set nocount on go while 1=1 begin begin tran update dbo.Employee_Demo_Heap set BirthDate = getdate() where NationalIDNumber = ‘480951955‘ select * from dbo.Employee_Demo_Heap where NationalIDNumber = ‘480951955‘ commit tran end 在另外一个连接里,也运行这些语句。唯一的差别是这次修改和查询的是另一条NationalIDNumber = ‘407505660’的记录。 set nocount on go while 1=1 begin begin tran update dbo.Employee_Demo_Heap set BirthDate = getdate() where NationalIDNumber = ‘407505660‘ select * from dbo.Employee_Demo_Heap where NationalIDNumber = ‘407505660‘ commit tran end
标签:
原文地址:http://www.cnblogs.com/heqianjin/p/5698606.html