上一篇讲到锁定的概念,那么接下来就是如何找到由于锁定而发生阻塞的进程,并解决阻塞问题。
1、会话1,修改数据,但没有提交事务
-
BEGIN TRAN
-
-
select @@SPID --输出:287
-
-
UPDATE t
-
SET v = '88888'
-
WHERE idd = 1
2、会话2,由于会话一事务没有提交,导致阻塞
-
BEGIN TRAN
-
-
select @@SPID --输出:105
-
-
UPDATE t
-
SET v = '888'
-
WHERE idd = 1
-
--查询会话1的等待信息
-
select session_id, --查询的会话,也就是被阻塞的会话
-
wait_duration_ms, --等待毫秒数
-
wait_type, --等待类型,如:LCK_M_X表示正在等待获取排他锁
-
-
-
blocking_session_id --阻塞session_id会话的会话
-
from sys.dm_os_waiting_tasks
-
where session_id = 105
3、查询这个被阻塞的会话请求的资源情况
从输出结果看,会话2在update时一共获取了4个锁,共享数据库锁、2个意向独占锁(锁定表、数据页),
一个键锁锁住那条要更新的记录,只有这个键锁的请求状态时wait,
其他3个锁状态为grant表示已经会话2已经获得了锁。
-
select resource_type,
-
-
request_status,
-
request_mode,
-
request_session_id
-
-
from sys.dm_tran_locks
-
where request_session_id = 105
另一种查看阻塞会话的方法,查看当前会话的执行请求:
-
select session_id,
-
status,
-
-
blocking_session_id,
-
wait_type,
-
wait_time
-
from sys.dm_exec_requests
-
where session_id = 105
4、 设置等待锁释放的时间
由于阻塞一段时间后,可能会超过设置的等待时间,返回锁定错误,所以,我们可以设置超时时段,以毫秒为单位。