常見的死鎖情況及解決方法
1、死鎖的第一種情況
一個使用者A 訪問表A(鎖住了表A),然後又訪問表B;另一個使用者B 訪問表B(鎖住了表B),然後企圖訪問表A;這時使用者A由於使用者B已經鎖住表B,它必須等待使用者B釋放表B才能繼續,同樣使用者B要等使用者A釋放表A才能繼續,這就死鎖就產生了。
解決方法
這種死鎖比較常見,是由於程式的BUG產生的,除了調整的程式的邏輯沒有其它的辦法。仔細分析程式的邏輯,對於資料庫的多表操作時,儘量按照相同的順序進行處理,儘量避免同時鎖定兩個資源,如操作A和B兩張表時,總是按先A後B的順序處理, 必須同時鎖定兩個資源時,要保證在任何時刻都應該按照相同的順序來鎖定資源。
2、死鎖的第二種情況
使用者A查詢一條紀錄,然後修改該條紀錄;這時使用者B修改該條紀錄,這時使用者A的事務裡鎖的性質由查詢的共享鎖企圖上升到獨佔鎖,而使用者B裡的獨佔鎖由於A有共享鎖存在所以必須等A釋放掉共享鎖,而A由於B的獨佔鎖而無法上升的獨佔鎖也就不可能釋放共享鎖,於是出現了死鎖。這種死鎖比較隱蔽,但在稍大點的專案中經常發生。如在某專案中,頁面上的按鈕點選後,沒有使按鈕立刻失效,使得使用者會多次快速點選同一按鈕,這樣同一段程式碼對資料庫同一條記錄進行多次操作,很容易就出現這種死鎖的情況。
解決方法
對於按鈕等控制元件,點選後使其立刻失效,不讓使用者重複點選,避免對同時對同一條記錄操作。
使用
樂觀鎖
進行控制。樂觀鎖大多是基於資料版本(Version
)記錄機制實現。即為資料增加一個版本標識,在基於資料庫表的版本解決方案中,一般是通過為資料庫表增加一個“version”
欄位來實現。讀取出資料時,將此版本號一同讀出,之後更新時,對此版本號加一。此時,將提交資料的版本資料與資料庫表對應記錄的當前版本資訊進行比對,如果提交的資料版本號大於資料庫表當前版本號,則予以更新,否則認為是過期資料。樂觀鎖機制避免了長事務中的資料庫加鎖開銷(使用者A和使用者B操作過程中,都沒有對資料庫資料加鎖),大大提升了大併發量下的系統整體效能表現。Hibernate
在其資料訪問引擎中內建了樂觀鎖實現。需要注意的是,由於樂觀鎖機制是在我們的系統中實現,來自外部系統的使用者更新操作不受我們系統的控制,因此可能會造成髒資料被更新到資料庫中。update goods set store=store-1,version=version+1 where id=xx and version=orginal_version
使用悲觀鎖進行控制。悲觀鎖大多數情況下依靠資料庫的鎖機制實現,如Oracle的
Select … for update
語句,以保證操作最大程度的獨佔性。但隨之而來的就是資料庫效能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受。如一個金融系統,當某個操作員讀取使用者的資料,並在讀出的使用者資料的基礎上進行修改時(如更改使用者賬戶餘額),如果採用悲觀鎖機制,也就意味著整個操作過程中(從操作員讀出資料、開始修改直至提交修改結果的全過程,甚至還包括操作員中途去煮咖啡的時間),資料庫記錄始終處於加鎖狀態,可以想見,如果面對成百上千個併發,這樣的情況將導致災難性的後果。所以,採用悲觀鎖進行控制時一定要考慮清楚。死鎖的第三種情況
如果在事務中執行了一條不滿足條件的update
語句,則執行全表掃描,把行級鎖上升為表級鎖,多個這樣的事務執行後,就很容易產生死鎖和阻塞。類似的情況還有當表中的資料量非常龐大而索引建的過少或不合適的時候,使得經常發生全表掃描,最終應用系統會越來越慢,最終發生阻塞或死鎖。
解決方法
SQL語句中不要使用太複雜的關聯多表的查詢;使用“執行計劃”對SQL語句進行分析,對於有全表掃描的SQL語句,建立相應的索引進行優化
文章來源:https://www.douban.com/note/344647957/?type=like
相關文章
- MySQL併發時經典常見的死鎖原因及解決方法MySql
- SQ死鎖及死鎖的解決
- 解決Oracle死鎖的快捷方法Oracle
- 死鎖檢測及解決
- Nacos 常見問題及解決方法
- DVR常見故障原因及解決方法VR
- Hadoop常見問題及解決方法Hadoop
- KMP常見問題及解決方法【Z】KMP
- Solaris 常見問題及解決方法(轉)
- mysql之神奇的死鎖及解決思路MySql
- DNS故障的幾種常見原因及解決方法DNS
- Oracle 常見的錯誤問題及解決方法Oracle
- MYSQL RC模式insert update 可能死鎖的情況MySql模式
- javaWeb常見異常的解決方法JavaWeb
- Oracle資料表死鎖的解決方法Oracle
- synchronized 內部原理、常見鎖策略、CAS、 以及死鎖的產生和解決synchronized
- 網路交換機常見故障及解決方法
- MySQL死鎖系列-常見加鎖場景分析MySql
- 記憶體混亂及解決方法和死鎖問題記憶體
- oracle 死鎖解決方法一例Oracle
- 常見問題及解決
- MySQL 死鎖解決MySql
- MySQL解決死鎖MySql
- ORA-00060死鎖的產生及解決
- oracle 死鎖表解決方法Oracle
- As常見問題解決方法
- 常見等待事件的分析解決方法事件
- CentOS 常見異常及解決辦法CentOS
- Java 程式死鎖問題原理及解決方案Java
- Git常見問題及解決Git
- 常見問題及解決方案
- oracle死鎖的檢視及kill方法Oracle
- 中科三方——SSL常見錯誤及解決方法
- SSL證書7大常見錯誤及解決方法!
- maven jar包衝突常見報錯及解決方法MavenJAR
- Kafka常見的問題及解決方案Kafka
- dede常見漏洞以及解決方法
- UltraEdit常見問題及解決教程