最近給客戶做優化時,有幾個客戶都存在.SLEEPING 會話中開啟了事務,導致的大量阻塞,從而產生嚴重的性能問題。雖然在之前的文章我分享了Sleeping會話導致阻塞原理(上) 。說明了什么是Sleeping會話,以及他可能導致的問題。但是對如何解決問題,給出的方案,還是太簡單了,沒有給出解決的細節。本文將對這些細節進行說明。希望大家面對類似問題時更容易下手
下面分享2個案例,分別針對針對問題來著存儲過程 和 程序 中的情況。
以下是某醫藥公司的案例截圖:
從圖中可以看到,230 處于SLEEPING 狀態并且產生了大量的阻塞。查看子語句可以知道230運行的是一個存儲過程。
問題就在于:在這個存儲過程中,開啟事務(如下圖所示),并且運行到后面某個語句時出錯了(可能是超時,或者其他錯誤)。但是開啟的事務并沒有回滾.
有的同學,可能知道,在存儲過程中 加入tray catch ,出錯時回滾事務。這個解決辦法并不徹底。對應有些錯誤是無法捕捉,對應這種情況,,我們可以在存儲過程中直接加上:SET XACT_ABORT ON 。當存儲過程執行時發生問題時,會自動回滾所有事務,從而避免了阻塞。
這是某制造行業的財務的案例截圖:
查看子語句,和父語句都是單獨的一個查詢,說明3185 開啟的事務來著 程序0
對應這種情況,只能修改程序。因為客戶的代碼不好分享,下面是我自己寫的測試程序代碼:
在修改時有幾個細節需要注意:
1.在代碼中加入TRY CATCH。
2.在CATHC 中必須使用close,dispose 來關閉連接,當然使用了using也是可以的3.程序建立了新的連接,并執行了查詢。此時會出現 sp_reset_connection事件,此時,事務會被回滾。注意 。兩次建立連接的connectsting.就是連接字符串必須完全一致。多個;都不可以。
只有滿足上面3個條件,,sleeping狀態的的會話對應是事務才會被回滾。從而解除上面的阻塞。
在解決實際問題時,在知道解決辦法后,還有很多技術細節,這是我們必須要關注的
新聞熱點
疑難解答