查看系統視圖sys.dm_tran_locks 當前有哪些鎖
select request_session_id ,request_mode,*
from
sys.dm_tran_locks
where
resource_type='OBJECT'
其中
request_session_id 代表鎖類型
request_mode 代表進程id
如果需要kill掉造成鎖的進程、
執行
kill *** ---查到的 request_session_id
抓取造成鎖的sql
select er.session_id, CAST(csql.text AS varchar(max)) AS CallingSQL
from master.sys.dm_exec_requests er WITH (NOLOCK)
CROSS APPLY fn_get_sql (er.sql_handle) csql
where er.session_id in (select
request_session_id
from
sys.dm_tran_locks
where
resource_type='OBJECT'
and request_mode ='X')
這裏我們抓取造成X(排他)鎖 的sql語句、
查看語句進行分析、
舉個例子:
IF EXISTS ( SELECT *
FROM tempdb.dbo.sysobjects
WHERE id = OBJECT_ID(N'tempdb..#tmp_HomeVisitOrders')
AND type = 'U' )
以上語句會 對sys.sysschobjs 這個表上的聚集索引上產生一個S(共享)鎖、
創建臨時表時在事務內、 並且未提交的時候、 就會對 sys.sysschobjs 這個表上的聚集索引上產生一個X(排他)鎖、
由於排他鎖導致其他進程獲取不到共享鎖、所以產生等待、
出現阻塞的進程、
進而用戶反饋系統卡頓、
建議將創建臨時表的語句移出事務外執行、(mysql是不允許在事務內創建臨時表的、sqlserver 沒有限制)
或
IF OBJECT_ID(N'tempdb..#tmp_FlowHomeVisit_Tasks') IS NOT NULL
BEGIN
DROP TABLE #tmp_FlowHomeVisit_Tasks;
END;
如此這般、
備註:
不建議直接kill掉對應進程、
建議先查明原因、
想辦法規避、