1. 程式人生 > >《HighPerformance MySQL》概譯 死鎖

《HighPerformance MySQL》概譯 死鎖

當多個事務同時持有和請求同一資源上的鎖而產生迴圈依賴的時候就產生了死鎖。死鎖發生在事務試圖以不同的順序鎖定資源。以StockPrice表上的兩個事務為例:

事務1
START TRANSACTION;
UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4 and date = '2002-05-01';
UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3 and date = '2002-05-02';
COMMIT;
事務 #2
START TRANSACTION;
UPDATE StockPrice SET high = 20.12 WHERE stock_id = 3 and date = '2002-05-02';
UPDATE StockPrice SET;
COMMIT;

如果不走運的話,每個事務都可以執行完第一個語句,並在過程中鎖住資源。然後每個事務都試圖去執行第二行語句,當時卻發現它被鎖住了。兩個事務將永遠的等待對方完成,除非有其他原因打斷死鎖。

為了解決這個問題,資料庫實現了各種死鎖探查和超時機制。像InnoDB這樣複雜的儲存引擎會提示迴圈依賴並且立即返回錯誤。否則死鎖將會導致查詢非常緩慢。其他一些不好的做法是等待超時後放棄。當前InnoDB處理死鎖的方式是回滾持有最少排他行級鎖的事務。(幾乎最簡單的回滾的參考指標)

鎖的行為是順序是儲存引擎決定的。因此,一些儲存引擎可能會在特定的操作順序下發生死鎖,其他的可能沒有。死鎖有兩種:一些是因為實際資料衝突而無法避免,一些是因為儲存引擎的工作方式產生。

只有部分或者完全回滾其中的一個事務才可能打破死鎖。死鎖是事務系統中客觀存在的事實,你的應該在設計上必須應該考慮處理死鎖。一些業務系統可以從頭重試事務。