3 回答

TA貢獻1811條經(jīng)驗 獲得超5個贊
可以幫助解決大多數(shù)死鎖的一個簡單技巧是按特定順序?qū)Σ僮鬟M行排序。
當兩個事務(wù)試圖以相反的順序鎖定兩個鎖時,你會遇到死鎖,即:
連接1:鎖定鍵(1),鎖定鍵(2);
連接2:鎖定鍵(2),鎖定鍵(1);
如果兩者同時運行,則連接1將鎖定密鑰(1),連接2將鎖定密鑰(2),并且每個連接將等待另一個連接釋放密鑰 - >死鎖。
現(xiàn)在,如果您更改了查詢,連接將以相同的順序鎖定密鑰,即:
連接1:鎖定鍵(1),鎖定鍵(2);
連接2:鎖定鍵(1),鎖定鍵(2);
陷入僵局是不可能的。
所以這就是我的建議:
除了delete語句之外,確保沒有其他任何鎖定訪問多個密鑰的查詢。如果你這樣做(我懷疑你這樣做),請按升序排列他們的WHERE(k1,k2,.. kn)。
修復(fù)delete語句以升序工作:
更改
DELETE FROM onlineusers WHERE datetime <= now() - INTERVAL 900 SECOND
至
DELETE FROM onlineusers WHERE id IN (SELECT id FROM onlineusers WHERE datetime <= now() - INTERVAL 900 SECOND order by id) u;
另外要記住的是mysql文檔建議在遇到死鎖的情況下,客戶端應(yīng)該自動重試。您可以將此邏輯添加到客戶端代碼中。(比如,在放棄之前對此特定錯誤進行3次重試)。

TA貢獻2036條經(jīng)驗 獲得超8個贊
delete語句很可能會影響表中總行數(shù)的很大一部分。最終,這可能會導(dǎo)致在刪除時獲取表鎖。持有鎖(在這種情況下是行鎖或頁鎖)并獲得更多鎖定始終是一種死鎖風險。但是我無法解釋為什么insert語句導(dǎo)致鎖升級 - 它可能與頁面拆分/添加有關(guān),但是更好地了解MySQL的人必須填寫那里。
首先,可以嘗試立即為delete語句顯式獲取表鎖。
添加回答
舉報