處理鎖 阻塞和死鎖(2) 偵測阻塞和阻塞查詢

2021-06-28 02:31:57 字數 4654 閱讀 9705

如果乙個事務正在等待一些給其他事務鎖定的資源。這個事務就被成為「被阻塞的事務」。反過來,引起阻塞的事務,也就是鎖定資源並造成其他事務等待的事務叫做「正在阻塞的事務」。

長時間執行事務會阻塞其他事務和查詢,使他們等待長時間。在繁重的系統中,很多時候我們會遇到阻塞問題,如果乙個事務因為阻塞未完成。會造成一些列的等待鏈。

本文將介紹如何發現並馬上解決這方面的問題。

本例依舊使用sqlserver2012上的adventureworks2012資料庫。

1、 連到sqlserver2012的adventureworks2012資料庫。

2、 新建視窗並輸入:

[sql]view plain

copy

print

?use adventureworks2012  

go  

set

transaction

isolation

level

repeatable

read

go  

--開啟事務

begin

transaction

--獲取會話id

select@@spidasconnection1_sessionid  

select*  

fromsales.salesorderdetail  

wheresalesorderdetailid = 121316  

use adventureworks2012

goset transaction isolation level repeatable read

go--開啟事務

begin transaction

--獲取會話id

select @@spid as connection1_sessionid

select *

from sales.salesorderdetail

where salesorderdetailid = 121316

3、 執行完之後,截圖如下:

4、 新開另外乙個視窗,輸入下面**去開啟另外乙個事務,留意update語句,將不會執行,因為在等待第二步中的事務:

[sql]view plain

copy

print

?use adventureworks2012  

go  

--開啟事務

begin

transaction

updatesales.salesorderdetail  

setorderqty = 10  

wheresalesorderdetailid = 121316  

commit

transaction

use adventureworks2012

go--開啟事務

begin transaction

update sales.salesorderdetail

set orderqty = 10

where salesorderdetailid = 121316

commit transaction

5、 再開啟乙個事務,輸入以下**查詢被阻塞和正在阻塞的查詢: 

[sql]view plain

copy

print

?selectr.session_idasblockedsessionid ,  

s.session_idasblockingsessionid ,  

q1.textasblockedsession_tsql ,  

q2.textasblockingsession_tsql ,  

c1.most_recent_sql_handleasblockedsession_sqlhandle ,  

c2.most_recent_sql_handleasblockingsession_sqlhandle ,  

s.original_login_nameasblockingsession_loginname ,  

s.program_nameas

s.host_name as blockingsession_hostname  

fromsys.dm_exec_requestsasr  

inner

join

sys.dm_exec_sessionsassonr.blocking_session_id = s.session_id  

inner

join

sys.dm_exec_connectionsasc1onr.session_id = c1.most_recent_session_id  

inner

join

sys.dm_exec_connectionsasc2ons.session_id = c2.most_recent_session_id  

cross

q1  

cross

q2  

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.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

6、 因為第乙個連線占用了資源,阻塞了其他事務,所以這裡要結束這個程序:

[sql]view plain

copy

print

?kill 68  

go  

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

from:

阻塞和死鎖

阻塞和死鎖是兩個不同的概念。舉個例子,現在有執行緒1和執行緒2,執行緒1占用了資源a,執行緒2占用了資源b。此時執行緒2需要使用資源a才能繼續,但是資源a被執行緒1所占用,那麼執行緒2只能等待資源a被執行緒1釋放掉,這種情況稱為執行緒2被阻塞。但是,如果此時執行緒1也許要資源b才能繼續,那麼兩個執行...

資料庫阻塞和死鎖

資料庫阻塞和死鎖在程式開發過程經常出現,怎麼樣避免呢?下面通過demo簡單模擬下,資料庫發生阻塞和死鎖的現象 一 資料庫阻塞 資料庫阻塞的現象 第乙個連線占有資源沒有釋放,而第二個連線需要獲取這個資源。如果第乙個連線沒有提交或者回滾,第二個連線會一直等待下去,直到第乙個連線釋放該資源為止。對於阻塞,...

阻塞和死鎖問題整理一

阻塞和死鎖問題整理 顯示資料庫test的鎖資訊sp sp lock 獲取使用者資訊 sp who or sp who2 select from sys.sysprocesses as sps with nolock or select sps.spid,sps.kpid sps.blocked sp...