死锁原因的排查
思韵闪耀
2012-06-08
0

1,打开跟踪,写入日志
DBCC TRACEON (3605,1222,-1) –3605写入errorlog,1222死锁
DBCC TRACEON(1222,-1) /若在启动时,加-T 1222
同时,可开profile中的Deadlock graph跟踪,以图形化
2,分析安装目录下生成的日志
   1)确定死锁的资源, 据对象不同查看方式不同。
DBCC TRACEON(3604)

DBCC PAGE(8,1,96,1)
DBCC TRACEOFF(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


【版权声明】
本站部分内容来源于互联网,本站不拥有所有权,不承担相关法律责任。如果发现本站有侵权的内容,欢迎发送邮件至masing@13sy.com 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。

NAT

相关内容

docker-compos...
1.Compose介绍 DockerCompose是一个用来定义和...
2024-04-26
firewall-cmd ...
firewalld的简要说明:firewalld 、firewal...
2024-03-15
centos7 firew...
名词解释 在具体介绍zone之前学生先给大家介绍几个相关的名词,因...
2023-12-22
数字证书和加密Exchan...
加密和数字证书是所有组织的重要考虑因素。 默认情况下,Exchan...
2022-09-16
Docker的一系列操作(...
首先要清楚Redis是安装在Docker容器,所以要进行很长的Do...
2022-09-08
MySQL 用户权限详细汇...
MySQL 用户权限详细汇总 1,MySQL权限体系 mysql ...
2022-03-17

热门资讯

sql中int型与varcha... sql中int转varchar或nvarchar,varchar或nvarchar转int的方法: ...
SQLSERVERAGENT ... 上的 SQLSERVERAGENT 服务启动过,然后又停止了。 (ObjectExplorer) 可...
SQL Server 中4个系... SQL Server 中4个系统数据库,Master、Model、Msdb、Tempdb 系统数据库...
SQL Server中如何设置... 对于已经建好的数据库表,是不能在SQL Server Management中可视化地修改ID为自增长...
该表已为了复制而被发布,所以... 场景:从发布库上将一数据库移到另一服务器,在对表改名时提示该表已为了复制而被发布,所以无法重命名。 ...
SQL Server 2008... SQL Server 2008 R2运行越久,占用内存会越来越大。 第一种: 有了上边的分析结果,解...
SQL Server (MSS... SQL Server (MSSQLSERVER) 启动后 自动生成文件 audittrace2022...
如果使用没有提供选项值的 Sq... 如果使用没有提供选项值的 SqlDependency,必须先调用 SqlDependency.Sta...
传递给数据库 'master'... 传递给数据库 master 中的日志扫描操作的日志扫描号无效 错误:连接数据库的时候提示:SQL S...
数据仓库SSAS+SSIS+... 数据仓库SSAS+SSIS+SSRS SSAS- 1,用ssas生成多维度,然后利用excel的da...