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