解決session阻塞的問題

2021-09-21 04:43:41 字數 3544 閱讀 4089

原文:解決session阻塞的問題

對於資料庫運維人員來說建立session或者查詢時產生問題是常規情況,下面介紹一種很有效且不借助第三方工具的方式來解決類似問題。

最近開始接觸運維工作,所以自己總結一些方案便於不懂資料庫的同事解決一些不太緊要的資料庫問題。類似方法很多理論也很多,我就不做深究,就是簡單寫乙個方案,便於菜鳥使用的。

sql server中當乙個資料庫會話中的事務正鎖定乙個或多個其他會話事務想要讀取或修改的資源時,會產生阻塞(blocking)。通常短時間的阻塞沒有問題,且是較忙的應用程式所需要的。然而,設計糟糕的應用程式會導致長時間的阻塞,這就不必要地鎖定了資源,而且阻塞了其他會話讀取和更新它們。

為了更好說明,下面用乙個例子來介紹。建立乙個表並插入資料,然後建立不同的session,同事阻塞session。具體的**截圖如下:

1.建立表employee

2.插入測試資料

現在我們有了測試表,表中有12條資料,開啟另乙個查詢對話方塊在ssms中(意味著重新建立了乙個session)

3.在新的查詢視窗中首先要開啟事務,然後寫乙個插入語句

在這個地方,我們能看到開啟了乙個事務。但是沒有end tran 來終止事務,因此事務狀態為「open」,現在執行指令碼來看一下當前看起的執行處於「open」狀態的session。

現在能夠看到如上圖展示一樣,執行的查詢正在open狀態的session。我們執行了這個命令但是沒有完結它,dba會聯絡這個session的建立者來完成事務,或者回滾事務。

現在讓我們建立另乙個session,更新一條記錄並且不提交,即讓查詢session的狀態為「open」。因此在新的查詢視窗中 寫乙個語句來執行如下:

這裡會看到系統正在執行後沒有完成語句的狀態(因為上乙個事務沒有關閉導致表鎖,這個不能插入),現在可以在另外的視窗查詢一下阻塞的情況,如下檢查阻塞的session。

如上所示,阻塞的session id是58,由於我們更新查詢導致阻塞了54的執行,54就是我們插入資料未提交的批處理。

現在我們能搞清楚阻塞的原因,也就可以從容解決阻塞了。

在了解業務的情況下,可以直接使用kill session id的語句來終止某個阻塞的session。

在執行的事務的起始加入「set lock_timeout 1000」 語句,這表示如果阻塞超過1000毫秒,這個請求將被終止。

回滾或者提交事務。這個就不細說了。

下面是所有語句的**:

/*

***creating dummy table employee ***

*/create

table employee ( empid int

notnull, name nchar(10) null, city nchar(10) null ) on

[primary]go

/**** insert dummy data in employee table ****

*/insert

into employee values(1245,'

george

','jax

'), (1045,'

peter

','anadale

'), (1157,'

john

','dallas

'), (1175,'

pete

','topeka

'), (875,'

petron

','vienna

'),

(2311,'

kohli

','mumbai

'), (1547,'

peter

','kansas

'), (3514,'

abian

','khi

'), (4251,'

ghani

','alexandria

'), (957,'

ahmed

','vienna

'), (1084,'

bhanu

','manderin

'),

(2954,'

ganeshan

','mcclean

')/*

**** insert query in new session ***

*/begin

tran

insert

into employee values(1245,'

george

','jax

') /*

*** query to check currently running sessions ***

*/select

distinct name as database_name, session_id, host_name, login_time, login_name, reads, writes from sys.dm_exec_sessions

left

outer

join sys.dm_tran_locks on sys.dm_exec_sessions.session_id = sys.dm_tran_locks.request_session_id

inner

join sys.databases on sys.dm_tran_locks.resource_database_id = sys.databases.database_id

where resource_type <>

'database

'--and name ='specific db name'

order by name
自己也使用過多種不同的語句來查詢定位阻塞甚至死鎖,然後解決,這裡也是介紹一種臨時解決方式。萬變不離其宗,歸根結底還是因為**甚至資料庫設計上存在很多問題才導致的阻塞,比如缺失索引、事務中的查詢效能和邏輯順序存在問題、t-sql語句效能引起的等等不一而足。對於一些常年解決類似問題的dba人員來說沒啥價值,但是對於不太理解資料庫的人來說還是能暫時解決一些緊急問題,當然最後還是要把理論基礎打好才能盡可能的杜絕類似情況。

session阻塞的問題

對於資料庫運維人員來說建立session或者查詢時產生問題是常規情況,下面介紹一種很有效且不借助第三方工具的方式來解決類似問題。最近開始接觸運維工作,所以自己總結一些方案便於不懂資料庫的同事解決一些不太緊要的資料庫問題。類似方法很多理論也很多,我就不做深究,就是簡單寫乙個方案,便於菜鳥使用的。在sq...

關於SESSION 阻塞問題

關於session 阻塞問題 當開啟 session 後,一般都是等待指令碼執行完成後自動關閉 如果需要處理某些資料時,執行的時間比較長 如5 6秒時 而處理的進度寫入session 中,這時頁面執行乙個ajax去獲取當前執行的進度時,就會出現 session 阻塞的問題。解決方式 在需要讀寫 se...

PHP中Session引起的指令碼阻塞問題解決辦法

解決session阻塞問題的辦法 在session操作完成後呼叫session write close 即可避免此問題 案例一 使用session過程中,在開啟session後,同一瀏覽器,執行同一程式,不同頁面會被鎖。不同瀏覽器不會出現這種情況。疑問 是不是session start導致了阻塞?於...