之前遇到過這么一種情況:
連接數(shù)據(jù)庫的部分Session會出現(xiàn)不定時的阻塞,這種阻塞時長時短,有時候持續(xù)較長時間,有時間持續(xù)時間較短,沒有什么規(guī)律。
之后分析相關(guān)存儲過程和代碼寫法,發(fā)現(xiàn)是阻塞源頭的存儲過程中開啟了事務(wù),而應(yīng)用程序在調(diào)用存儲過程發(fā)生異常之后沒有進(jìn)行特別的處理(提交或者回滾),
那么在執(zhí)行方法發(fā)生異常之后,連接關(guān)閉了,但是數(shù)據(jù)庫中遺留有活動事務(wù)(dbcc opentran對應(yīng)的SessionId是sleeping狀態(tài)),于是就產(chǎn)生了阻塞。
關(guān)鍵是活動事務(wù)會不定時自己消失,就有點詭異了,這是本文的重點。
這種機制跟連接池有關(guān):
當(dāng)應(yīng)用程序連接數(shù)據(jù)庫的時候開啟了連接池,如果應(yīng)用程序調(diào)用了一個開啟了事務(wù)操作的存儲過程,
當(dāng)發(fā)生異常的時候,有可能會出現(xiàn)數(shù)據(jù)庫連接關(guān)閉,而存儲過程中的事務(wù)既沒有提交,也沒有回滾的情況。
這種情況下就會產(chǎn)生“孤立事務(wù)”,也就是說,因為打開事務(wù)的數(shù)據(jù)量連接斷掉了,而事務(wù)還處于活動狀態(tài),
實際上開啟連接池的情況下,數(shù)據(jù)庫連接的關(guān)閉,并不是物理上的關(guān)閉,而是將數(shù)據(jù)庫連接返回到連接池。
此時如果沒有外界的干預(yù),包括沒有對這個數(shù)據(jù)庫連接沒有被重用,或者這個連接沒有物理斷開,或者是沒有重啟應(yīng)用程序,或者沒有數(shù)據(jù)庫服務(wù)器,這個事務(wù)將一直持續(xù)下去。
因為活動事務(wù)將阻塞其他Session對相關(guān)表的排他性訪問,所以就表現(xiàn)為阻塞。
如何判斷是否發(fā)生了連接池中的連接重用
首先,一個連接數(shù)據(jù)庫的過程中,有沒有重用連接池中的連接,在SQL Server中有哪些區(qū)別?
以ado.net為例,如果在連接字符串中加入pooling=false;則表示不啟用連接池.
如下,連續(xù)執(zhí)行兩次數(shù)據(jù)庫訪問,兩次數(shù)據(jù)庫訪問均在連接字符串中加入了pooling=false;表示不啟用連接池
延伸閱讀
- ssh框架 2016-09-30
- 阿里移動安全 [無線安全]玩轉(zhuǎn)無線電——不安全的藍(lán)牙鎖 2017-07-26
- 消息隊列NetMQ 原理分析4-Socket、Session、Option和Pipe 2024-03-26
- Selective Search for Object Recognition 論文筆記【圖片目標(biāo)分割】 2017-07-26
- 詞向量-LRWE模型-更好地識別反義詞同義詞 2017-07-26
- 從棧不平衡問題 理解 calling convention 2017-07-26
- php imagemagick 處理 圖片剪切、壓縮、合并、插入文本、背景色透明 2017-07-26
- Swift實現(xiàn)JSON轉(zhuǎn)Model - HandyJSON使用講解 2017-07-26
- 阿里移動安全 Android端惡意鎖屏勒索應(yīng)用分析 2017-07-26
- 集合結(jié)合數(shù)據(jù)結(jié)構(gòu)來看看(二) 2017-07-26