共計 1169 個字符,預計需要花費 3 分鐘才能閱讀完成。
這篇“MySQL 如何批量更新死鎖”文章的知識點大部分人都不太理解,所以丸趣 TV 小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“MySQL 如何批量更新死鎖”文章吧。
表結構如下:
CREATE TABLE `user_item` ( `id` BIGINT(20) NOT NULL,
`user_id` BIGINT(20) NOT NULL,
`item_id` BIGINT(20) NOT NULL,
`status` TINYINT(4) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_1` (`user_id`,`item_id`,`status`)) ENGINE=INNODB DEFAULT CHARSET=utf-8
SQL 語句如下:
update user_item set status=1 where user_id=? and item_id=?
原因分析:
mysql 的事務支持與存儲引擎有關,MyISAM 不支持事務,INNODB 支持事務,更新時采用的是行級鎖。這里采用的是 INNODB 做存儲引擎,意味著會將 update 語句做為一個事務來處理。前面提到行級鎖必須建立在索引的基礎,這條更新語句用到了索引 idx_1,所以這里肯定會加上行級鎖。 行級鎖并不是直接鎖記錄,而是鎖索引,如果一條 SQL 語句用到了主鍵索引,mysql 會鎖住主鍵索引;如果一條語句操作了非主鍵索引,mysql 會先鎖住非主鍵索引,再鎖定主鍵索引。
這個 update 語句會執行以下步驟:
由于用到了非主鍵索引,首先需要獲取 idx_1 上的行級鎖
緊接著根據主鍵進行更新,所以需要獲取主鍵上的行級鎖;
更新完畢后,提交,并釋放所有鎖。
如果在步驟 1 和 2 之間突然插入一條語句:update user_item …..where id=? and user_id=?, 這條語句會先鎖住主鍵索引,然后鎖住 idx_1。
蛋疼的情況出現了,一條語句獲取了 idx_1 上的鎖,等待主鍵索引上的鎖;另一條語句獲取了主鍵上的鎖,等待 idx_1 上的鎖,這樣就出現了死鎖。
解決方案:
先獲取需要更新的記錄的主鍵
select id from user_item where user_id=? and item_id=?
逐條更新
update user_item set status=? where id=? and user_id=?
批量循環重復第一步和第二步即可
以上就是關于“MySQL 如何批量更新死鎖”這篇文章的內容,相信大家都有了一定的了解,希望丸趣 TV 小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注丸趣 TV 行業資訊頻道。
向 AI 問一下細節
丸趣 TV 網 – 提供最優質的資源集合!
正文完