首页 > 代码库 > SQL Server 阻塞排除的 2 方法

SQL Server 阻塞排除的 2 方法

背景知识:

            是什么造成了阻塞?

            从锁的观点来看、可访问对象前一定要对对象加锁不管你是读还是写,如果用户A以经持有对象,说明A以在对象上加锁,如果这时B

            也想访问这个对象、它也要对对象加锁。重点来了如果A用户加的是排它锁,B用户可以做的就是乖乖等A用完再说。B乖乖等这个问题

            就是阻塞,是因为这两把锁不可以共存才造成了阻塞。

场景再现:

            为在再现场景我们要开三个通向数据的连接。就是说要打开三个managerment studio 或是开三个sqlcmd。我用ssms(SQL Server Managerment Studio)为例

            先为场景做点准备,代码如下。

            use Studio;
            go

            create table TestTable (ID int not null,String nchar(10));
            go

            declare @i as int =1;
            while @i<10
            begin
            insert into TestTable(ID,String) values(@i,REPLICATE(cast(@i as nchar(1)),10));
            set @i = @i +1;
            end;
            go

            select T.ID,T.String from TestTable as T;

            go

            

           连接A运行如下代码:

                                    begin tran
                                    update dbo.TestTable
                                    set String = ‘AAA‘
                                    where ID=1;
                                    go --可以看到A会一直持有第一行上的排它锁,直到事务被commit 或 rollback!

           连接B运行如下代码:                             

                                    update dbo.TestTable
                                    set String = ‘BBB‘
                                    where ID=1; 

                                    go -- 因A以在ID=1这一行上有排它锁,所以B只可以乖乖的等,这就造成了阻塞。下图可以看出B等了2分多钟了。

                                    

           C连接用来解除阻塞,运行代码马上就讲。

方法 1、 从锁入手

                        第一步、看谁在等待资源,以确定谁被阻塞、运行如下代码

                                 select
                                 tra.request_session_id as [SessionID],-- 会话名
                                 DB_NAME(tra.resource_database_id) as [DBName],-- 数据库名
                                 tra.resource_type as [resourceType],-- 资源类型
                                 tra.resource_associated_entity_id as [ResourceID],--资源ID
                                 tra.request_status as [Status]  --状态
                                 from sys.dm_tran_locks as tra
                                 where tra.request_session_id>50;
                                 go

                                 

                                 -- 下图中可以看出有一行是wait 说明它在等别人,释放资源。

                                 所以 54 是在等别人,它等谁呢?从图上可以看出 51 持有54在等待对象的排它锁,说明54在等51。

                      第二步、定位等的是哪个资源:

                                                           运行如下代码

                                                           select OBJECT_NAME(565577053);--565577053来自于图上的倒数第二行。
                                                           go

                               

 

 

 

 

 

 

 

 

 

          

SQL Server 阻塞排除的 2 方法