第十六章——处理锁、阻塞和死锁(2)——侦测阻塞和阻塞查询

简介: 原文: 第十六章——处理锁、阻塞和死锁(2)——侦测阻塞和阻塞查询 前言: 如果一个事务正在等待一些给其他事务锁定的资源。这个事务就被成为“被阻塞的事务”。
原文: 第十六章——处理锁、阻塞和死锁(2)——侦测阻塞和阻塞查询

前言:

如果一个事务正在等待一些给其他事务锁定的资源。这个事务就被成为“被阻塞的事务”。反过来,引起阻塞的事务,也就是锁定资源并造成其他事务等待的事务叫做“正在阻塞的事务”。

长时间运行事务会阻塞其他事务和查询,使他们等待长时间。在繁重的系统中,很多时候我们会遇到阻塞问题,如果一个事务因为阻塞未完成。会造成一些列的等待链。

本文将介绍如何发现并马上解决这方面的问题。

 

准备工作:

本例依旧使用SQLServer2012上的AdventureWorks2012数据库。

 

步骤:

1、 连到SQLServer2012的AdventureWorks2012数据库。

2、 新建窗口并输入:

USE AdventureWorks2012
GO
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO

--开启事务
BEGIN TRANSACTION

--获取会话ID
SELECT  @@SPID AS Connection1_SessionID

SELECT  *
FROM    Sales.SalesOrderDetail
WHERE   SalesOrderDetailID = 121316


3、 执行完之后,截图如下:


4、 新开另外一个窗口,输入下面代码去开启另外一个事务,留意UPDATE语句,将不会执行,因为在等待第二步中的事务:


USE AdventureWorks2012
GO

--开启事务
BEGIN TRANSACTION

UPDATE  Sales.SalesOrderDetail
SET     OrderQty = 10
WHERE   SalesOrderDetailID = 121316

COMMIT TRANSACTION


5、 再开启一个事务,输入以下代码查询被阻塞和正在阻塞的查询: 

SELECT  R.session_id AS BlockedSessionID ,
        S.session_id AS BlockingSessionID ,
        Q1.text AS BlockedSession_TSQL ,
        Q2.text AS BlockingSession_TSQL ,
        C1.most_recent_sql_handle AS BlockedSession_SQLHandle ,
        C2.most_recent_sql_handle AS BlockingSession_SQLHandle ,
        S.original_login_name AS BlockingSession_LoginName ,
        S.program_name AS BlockingSession_ApplicationName ,
        S.host_name AS BlockingSession_HostName
FROM    sys.dm_exec_requests AS R
        INNER JOIN sys.dm_exec_sessions AS S ON R.blocking_session_id = S.session_id
        INNER JOIN sys.dm_exec_connections AS C1 ON R.session_id = C1.most_recent_session_id
        INNER JOIN sys.dm_exec_connections AS C2 ON S.session_id = C2.most_recent_session_id
        CROSS APPLY sys.dm_exec_sql_text(C1.most_recent_sql_handle) AS Q1
        CROSS APPLY sys.dm_exec_sql_text(C2.most_recent_sql_handle) AS Q2



6、 因为第一个连接占用了资源,阻塞了其他事务,所以这里要结束这个进程:


KILL 68
GO



7、 换回第二个查询界面,发现update操作已经成功完成。上面的进程号根据不同机器而定。


分析:

在本例中,把事务隔离级别设为REPEATABLE READ,因为在这个隔离级别中,在资源上的共享锁将持续到事务完成。所以当从表中查找数据是,该值上会加上共享锁。在事务提交或回滚前不会释放。

当执行第二个连接的update语句时,不能完成,因为被第一个事务阻塞了,且在REPEATABLE READ下共享锁不释放。

为了标识阻塞和被阻塞的请求,需要用到下面的DMO:

1、 dm_exec_requests

2、 dm_exec_sessions

3、 dm_exec_connections

4、 dm_exec_sql_text

 

 

目录
相关文章
|
监控 Go 数据库
第十六章——处理锁、阻塞和死锁(1)——确定长时间运行的事务
原文: 第十六章——处理锁、阻塞和死锁(1)——确定长时间运行的事务 前言: 事务是OLTP系统中的主要部分。它管理数据一致性和数据并发问题,当多个资源同时被读取或者修改相同数据时,SQLServer会通过锁定机制来确保数据库中的数据总是处于一个有效状态。
1296 0
|
8月前
|
消息中间件 算法 Java
(十四)深入并发之线程、进程、纤程、协程、管程与死锁、活锁、锁饥饿详解
本文深入探讨了并发编程的关键概念和技术挑战。首先介绍了进程、线程、纤程、协程、管程等概念,强调了这些概念是如何随多核时代的到来而演变的,以满足高性能计算的需求。随后,文章详细解释了死锁、活锁与锁饥饿等问题,通过生动的例子帮助理解这些现象,并提供了预防和解决这些问题的方法。最后,通过一个具体的死锁示例代码展示了如何在实践中遇到并发问题,并提供了几种常用的工具和技术来诊断和解决这些问题。本文旨在为并发编程的实践者提供一个全面的理解框架,帮助他们在开发过程中更好地处理并发问题。
137 0
死锁终结者:顺序锁和轮询锁!(4)
死锁终结者:顺序锁和轮询锁!(4)
146 0
死锁终结者:顺序锁和轮询锁!(4)
死锁终结者:顺序锁和轮询锁!(2)
死锁终结者:顺序锁和轮询锁!(2)
137 0
死锁终结者:顺序锁和轮询锁!(2)
死锁终结者:顺序锁和轮询锁!(1)
死锁终结者:顺序锁和轮询锁!(1)
127 0
死锁终结者:顺序锁和轮询锁!(1)
|
Java
死锁终结者:顺序锁和轮询锁!(5)
死锁终结者:顺序锁和轮询锁!(5)
138 0
死锁终结者:顺序锁和轮询锁!(3)
死锁终结者:顺序锁和轮询锁!(3)
115 0
死锁终结者:顺序锁和轮询锁!(3)
|
SQL 数据库
阻塞与死锁(三)——死锁的定位及解决方法
原文: 阻塞与死锁(三)——死锁的定位及解决方法 死锁所在的资源和检测: 在SQL Server的两个或多个任务中,如果某个任务锁定了其他任务试图锁定的资源。
1260 0