Sleeping會話導致阻塞原理(上)


背景

我在處理客戶問題的時候,客戶經常搞不懂sleeping 的由來,和他可能導致的問題。下面來詳細說下

 

什么是sleeping

 

其實我們經常可以在數據庫中看到“”sleeping“狀態的連接,但是這個sleeping 的狀態是怎么來的,如果有很多sleeping狀態的連接對數據庫有什么影響嗎?sleeping 代表建立了數據庫連接,但是,程序段沒有發出SQL命令. 因為很多應用程序為了減少打開和關閉連接的開銷,在完成數據庫中的操作后,仍然保持數據庫的連接。這些連接最主要的目的是重用。舉例:如果一個應用程序使用數據庫連接提取數據,如果已經存在一個連接可以重用,那么建立連接的消耗當然能夠最小化。那么,維護大量的sleeping連接會是一種開銷嗎?雖然,它相對來說是比較低的,但的確也是有開銷的。如果代碼編寫的合適,我們不應該看到大量的sleeping連接。

 

舉個栗子

新建一個控制台應用程序,先加入下面的代碼

1.建立連接並打開

SqlConnection sqlConnection = new SqlConnection("Server=(local);Database=Mydb;UId=test;Pwd=password;");
sqlConnection.Open();

查看數據庫會看到,此時就會出現SLEEPING狀態。這就是建立了連接但是沒有發出任何SQL命令

 

 2.SQL執行語句完成

我們執行下面的代碼 。在執行的過程中可能有(running,suspened,runnale狀態)等他執行完。查看數據庫中的狀態變為sleeping.

SqlCommand sqlCommand = new SqlCommand("select name from dbo.Student", sqlConnection);
sqlCommand.ExecuteScalar();

 

問題

 到目前為止,sleepig是怎么來的應該很清楚了,,但他可能到導致的問題是什么呢。具體看下面案例,

會話77就是sleeping操作,他阻塞了會話81,81又阻塞了75.  看看等待時間,,有點不忍直視了,數學好的同學可以數一下。   

 

這個問題怎么產生的呢? 其實就是在運行 sqlCommand.ExecuteScalar(); 的時候開啟了事務,但是這個語句由於超時或者查詢被取消了,會話變成了sleeping狀態。但是事務在數據庫中中還是開啟的狀態。

 

解決

通過查看上面圖中的工具,查看77 執行的語句,定位對應到程序中的代碼段,然后進行下面的改善措施:

1.在代碼中加入try catch的異常處理,在處理的的代碼中加入 :IF @@TRANCOUNT > 0 ROLLBACK TRAN

2.找到對應的執行的SQL,找出他執行超時的原因加以解決。

3.使用 SET XACT_ABORT ON; 他表示 如果執行 Transact-SQL 語句產生運行時錯誤,則整個事務將終止並回滾。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM