03.05 數據庫什麼時候會產生死鎖?

趙佳鑫15769579117


不鎖怕出事,鎖了又怕鎖死了!!!

數據庫由於數據存儲速度快,數據穩定,結構化的特性,被廣泛用作數據存儲,併成為最重要,最常見的方式!

數據庫從20世紀50年代誕生伊始,就因為支持事務的特性得到大力的發展,最終各種數據庫諸如oracle,Sybase,mysql等關係型數據庫百花齊放,既然數據庫是因為事務而生,那麼事務的特性又是哪些呢?簡而言之就是ACID(原子性,一致性,隔離性,持久性)!


而為了保持數據的一致性,數據庫都有了一個操作叫做加鎖!有表級鎖,行級鎖,頁面鎖!

死鎖就是說兩個線程在爭同一個資源,然後互不相讓,導致鎖死的情況(比如兩個人從兩端走上獨木橋,然後卡死在橋中間)!

回到問題本身,數據庫在什麼時候會產生死鎖呢?

1,情況一:我中有你,你中有我!

事務一:兩個操作update A;update B;

事務二:兩個操作update B;update A;

線程一執行事務一到一半的時候,鎖了A想要獲得B的鎖,與此同時事務二執行到了鎖B,想要獲得鎖A的時候,因為互相都想要對方擁有的鎖,而導致死鎖!

2,情況二:吃著碗裡的,看著鍋裡的!

A線程先查詢了一條記錄(使用了共享鎖),與此同時B線程正要修改這條記錄(使用了獨佔鎖),然後A線程突然想修改這條記錄了,怎麼辦呢?升級鎖。。而B線程想要降級為共享鎖,必須要等到A線程釋放掉共享鎖,這樣就形成了死鎖!

可以看到這個過程中是A佔著共享鎖想要升級,B佔著獨佔鎖想要降級,然後卡死!

3,牽一髮而動全身!

一個表結構,必須要有適當的索引等優化手段,如果在執行事務的時候,沒有加索引條件甚至沒有任何條件,那麼將執行全表掃描,如果是多個事務在操作,很容易就發生了阻塞和死鎖!所以字段加索引非常重要!!


可以說數據庫死鎖必然會造成很嚴重的生產事故,所以要儘量避免死鎖的發生,而如何避免呢?我會在後面的回答中逐一解答,敬請關注。。。


此生唯一


數據庫是一個軟件,是一個很多用戶會一起使用的軟件。

當多個用戶同時的去操作數據庫中數據的時候,在數據庫中就會產生多個用戶去存取同一條數據的情況。如果兩個或多個以上的用戶在執行的過程中,因爭奪資源導致互相等待,並且將一直等待下去,這種情況叫做死鎖。


產生死鎖的條件

  • 一條數據每次只能被一個用戶使用。

  • 一個用戶請求資源阻塞時,對已經獲得的資源保持不放

  • 用戶已經獲得的資源,未使用前,別人不能搶走

  • 幾個用戶形成首尾相接的循環等待資源

幾個條件同時發生的時候,就會產生思索。


比如小明和小紅都要做飯,做飯需要鏟子和鍋(加入鏟子和鍋各有一個)。

小明拿到了鏟子,準備去找鍋。

小紅拿到了鍋,準備去找鏟子。

然後他/她倆就僵持住了,每個人都拿著手上的東西不放手,於是就一直僵持下去了。

數據庫鎖類型

  • 排它鎖(X鎖):鎖上之後,其他用戶不能對其查詢和修改。

  • 共享鎖(S鎖):鎖上之後,其他用戶可以查詢,但是不能修改。


常見的產生死鎖的原因

  • 對相同的資源,訪問順序不相同:這個好理解吧,上面那個例子就是這個問題。小明做飯先找鏟子後找鍋,小紅做飯先找鍋後找鏟子。解決的方法也比較簡單,就是讓他們的順序保持一致就好了。

  • 索引失效:有時候索引失效導致查詢進行了全表掃描,執行全表掃描,會把行級鎖上升為表級鎖,如果這樣的事情發生次數太多,就很容易導致死鎖。解決方法也很簡單啦,別讓索引失效就好了。產生索引失效的原因也有很多,之前我有介紹過。

  • 併發修改同一記錄:用戶A先查詢一條數據,上了共享鎖,這時候用戶B要修改數據,上了獨佔鎖,賴好不好的,A也要做數據修改了,那麼共享鎖企圖上升為獨佔鎖。這時候,用戶B的獨佔鎖要等著A釋放共享鎖,但是A要做鎖升級,還必須等待B釋放獨佔鎖,於是出現了死鎖。數據庫解決這種問題,引入了悲觀鎖和樂觀鎖。這裡就不展開來說了。


希望我的回答能夠幫助到你!


分享到:


相關文章: