数据库及线程死锁(转)
來源:http://www.cnblogs.com/li-chong/p/3345139.html
什么是死鎖?
當(dāng)多個進(jìn)程同時訪問一個資源時,其中的每個進(jìn)程擁有的資源都是其他進(jìn)程所需的,由此造成的每個進(jìn)程都無法繼續(xù)下去的情況。
?
產(chǎn)生死鎖的原因主要是:
(1) 系統(tǒng)資源不足。
(2) 進(jìn)程運(yùn)行推進(jìn)的順序不合適。
(3) 資源分配不當(dāng)?shù)取?/p>
產(chǎn)生死鎖的四個必要條件:
(1)互斥條件:一個資源每次只能被一個進(jìn)程使用。
(2)請求與保持條件:一個進(jìn)程因請求資源而阻塞時,對已獲得的資源保持不放。
(3)不可剝奪條件:進(jìn)程已獲得的資源,在末使用完之前,不能強(qiáng)行剝奪。
(4)循環(huán)等待條件:若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
避免死鎖:
死鎖的預(yù)防是通過破壞產(chǎn)生條件來阻止死鎖的產(chǎn)生,但這種方法破壞了系統(tǒng)的并行性和并發(fā)性。
死鎖產(chǎn)生的前三個條件是死鎖產(chǎn)生的必要條件,也就是說要產(chǎn)生死鎖必須具備的條件,而不是存在這3個條件就一定產(chǎn)生死鎖,那么只要在邏輯上回避了第四個條件就可以避免死鎖。
避免死鎖采用的是允許前三個條件存在,但通過合理的資源分配算法來確保永遠(yuǎn)不會形成環(huán)形等待的封閉進(jìn)程鏈,從而避免死鎖。該方法支持多個進(jìn)程的并行執(zhí)行,為了避免死鎖,系統(tǒng)動態(tài)的確定是否分配一個資源給請求的進(jìn)程。
預(yù)防死鎖:
具體的做法是破壞產(chǎn)生死鎖的四個必要條件之一。
在系統(tǒng)設(shè)計、進(jìn)程調(diào)度等方面注意如何不讓這四個必要條件成立,如何確定資源的合理分配算法,避免進(jìn)程永久占據(jù)系統(tǒng)資源。此外,也要防止進(jìn)程在處于等待狀態(tài)的情況下占用資源,在系統(tǒng)運(yùn)行過程中,對進(jìn)程發(fā)出的每一個系統(tǒng)能夠滿足的資源申請進(jìn)行動態(tài)檢查,并根據(jù)檢查結(jié)果決定是否分配資源,若分配后系統(tǒng)可能發(fā)生死鎖,則不予分配,否則予以分配 。因此,對資源的分配要給予合理的規(guī)劃。
最大限度降低死鎖的產(chǎn)生的方法:
(1)按統(tǒng)一順序訪問對象
按同一順序訪問對象也就是:第一個事務(wù)提交或回滾后,第二個事務(wù)繼續(xù)進(jìn)行,這樣不會發(fā)生死鎖。
(2)避免事務(wù)中的用戶交互
? 避免編寫包含用戶交互的事務(wù),因?yàn)檫\(yùn)行沒有用戶交互的批處理的速度要遠(yuǎn)遠(yuǎn)快于用戶手動響應(yīng)查詢的速度,例如答復(fù)應(yīng)用程序請求參數(shù)的提示。例如,如果事務(wù)正在等待用戶輸入,而用戶去吃午餐了或者甚至回家過周末了,則用戶將此事務(wù)掛起使之不能完成。這樣將降低系統(tǒng)的吞吐量,因?yàn)槭聞?wù)持有的任何鎖只有在事務(wù)提交或回滾時才會釋放。即使不出現(xiàn)死鎖的情況,訪問同一資源的其它事務(wù)也會被阻塞,等待該事務(wù)完成。
(3)保持事務(wù)簡短并在一個批處理中:
在同一數(shù)據(jù)庫中并發(fā)執(zhí)行多個需要長時間運(yùn)行的事務(wù)時通常發(fā)生死鎖。事務(wù)運(yùn)行時間越長,其持有排它鎖或更新鎖的時間也就越長,從而堵塞了其它活動并可能導(dǎo)致死鎖。 保持事務(wù)在一個批處理中,可以最小化事務(wù)的網(wǎng)絡(luò)通信往返量,減少完成事務(wù)可能的延遲并釋放鎖。
(4)使用低隔離級別:
確定事務(wù)是否能在更低的隔離級別上運(yùn)行,執(zhí)行提交讀取允許事務(wù)讀取另一個事務(wù)已讀取(未修改)的數(shù)據(jù),而不必等待第一個事務(wù)完成。使用較低的隔離級別(例如提交讀取)而不使用較高的隔離級別(例如可串行讀)可以縮短持有共享鎖的時間,從而降低了鎖定爭奪。
(5)使用綁定連接:
使用綁定連接使同一應(yīng)用程序所打開的兩個或多個連接可以相互合作。次級連接所獲得的任何鎖可以象由主連接獲得的鎖那樣持有,反之亦然,因此不會相互阻塞。
?
對產(chǎn)生的死鎖的建議:
(1)對于頻繁使用的表使用集簇化的索引;
(2)設(shè)法避免一次性影響大量記錄的T-SQL語句,特別是INSERT和UPDATE語句;
(3)設(shè)法讓UPDATE和DELETE語句使用索引;
(4)使用嵌套事務(wù)時,避免提交和回退沖突;
(5)對一些數(shù)據(jù)不需要及時讀取更新值的表在寫SQL的時候在表后臺加上(nolock),如:Select * from tableA(nolock)
?
銀行家算法:
該算法需要檢查申請者對各類資源的最大需求量,如果現(xiàn)存的各類資源可以滿足當(dāng)前它對各類資源的最大需求量時,就滿足當(dāng)前的申請。換言之,僅當(dāng)申請者可以在一定時間內(nèi)無條件歸還它所申請的全部資源時,才能把資源分配給它。這樣申請者就可以很快完成其計算,然后釋放它占用的資源,從而保證了系統(tǒng)中的所有進(jìn)程都能完成,所以可以避免死鎖的發(fā)生。這種算法的主要問題是,要求每個進(jìn)程必須先知道資源的最大需求量,而且在系統(tǒng)的運(yùn)行過程中,考察每個進(jìn)程對各類資源的申請需花費(fèi)較多的時間。另外,這一算法本身也有些保守,因?yàn)樗偸强紤]最壞可能的情況。
轉(zhuǎn)載于:https://www.cnblogs.com/xiaoerlang/p/6496078.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的数据库及线程死锁(转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: XML 用途
- 下一篇: Intger To Roman