亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何避免mysql'試圖鎖定時發現死鎖; 嘗試重啟事務'

如何避免mysql'試圖鎖定時發現死鎖; 嘗試重啟事務'

慕斯王 2019-08-06 13:54:44
如何避免mysql'試圖鎖定時發現死鎖; 嘗試重啟事務'我有一個innoDB表記錄在線用戶。它會在用戶每次刷新頁面時更新,以跟蹤他們所在的頁面以及他們上次訪問網站的日期。然后,我有一個每15分鐘運行一次以刪除舊記錄的cron。我得到了一個'試圖鎖定時發現的死鎖; 嘗試重新啟動事務'昨晚約5分鐘,似乎是在這個表中運行INSERT。有人可以建議如何避免這個錯誤?===編輯===以下是正在運行的查詢:首次訪問網站:INSERT INTO onlineusers SETip = 123.456.789.123,datetime = now(),userid = 321,page = '/thispage',area = 'thisarea',type = 3在每個頁面刷新:UPDATE onlineusers SETips = 123.456.789.123,datetime = now(),userid = 321,page = '/thispage',area = 'thisarea',type = 3WHERE id = 888Cron每15分鐘一次:DELETE FROM onlineusers WHERE datetime <= now() - INTERVAL 900 SECOND然后它會記錄一些統計數據(即:在線成員,在線訪客)。
查看完整描述

3 回答

?
四季花海

TA貢獻1811條經驗 獲得超5個贊

可以幫助解決大多數死鎖的一個簡單技巧是按特定順序對操作進行排序。

當兩個事務試圖以相反的順序鎖定兩個鎖時,你會遇到死鎖,即:

  • 連接1:鎖定鍵(1),鎖定鍵(2);

  • 連接2:鎖定鍵(2),鎖定鍵(1);

如果兩者同時運行,則連接1將鎖定密鑰(1),連接2將鎖定密鑰(2),并且每個連接將等待另一個連接釋放密鑰 - >死鎖。

現在,如果您更改了查詢,連接將以相同的順序鎖定密鑰,即:

  • 連接1:鎖定鍵(1),鎖定鍵(2);

  • 連接2:鎖定鍵(1),鎖定鍵(2);

陷入僵局是不可能的。

所以這就是我的建議:

  1. 除了delete語句之外,確保沒有其他任何鎖定訪問多個密鑰的查詢。如果你這樣做(我懷疑你這樣做),請按升序排列他們的WHERE(k1,k2,.. kn)。

  2. 修復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文檔建議在遇到死鎖的情況下,客戶端應該自動重試。您可以將此邏輯添加到客戶端代碼中。(比如,在放棄之前對此特定錯誤進行3次重試)。


查看完整回答
反對 回復 2019-08-06
?
慕桂英3389331

TA貢獻2036條經驗 獲得超8個贊

delete語句很可能會影響表中總行數的很大一部分。最終,這可能會導致在刪除時獲取表鎖。持有鎖(在這種情況下是行鎖或頁鎖)并獲得更多鎖定始終是一種死鎖風險。但是我無法解釋為什么insert語句導致鎖升級 - 它可能與頁面拆分/添加有關,但是更好地了解MySQL的人必須填寫那里。

首先,可以嘗試立即為delete語句顯式獲取表鎖。


查看完整回答
反對 回復 2019-08-06
  • 3 回答
  • 0 關注
  • 1043 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號