首頁  >  文章  >  資料庫  >  一文詳解MySQL怎麼批量更新死鎖

一文詳解MySQL怎麼批量更新死鎖

藏色散人
藏色散人轉載
2023-04-13 16:32:371591瀏覽

這篇文章為大家帶來了關於MySQL的相關知識,其中主要跟大家聊聊MySQL怎麼批量更新死鎖,有程式碼範例,有興趣的朋友下面一起來看一下吧,希望對大家有幫助。

一文詳解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語句會執行下列步驟:

  1. 由於用到了非主鍵索引,首先需要取得idx_1上的行級鎖定

  2. ##緊接著依照主鍵進行更新,所以需要取得主鍵上的行級鎖定;

  3. 更新完畢後,提交,並釋放所有鎖定。

如果在步驟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=?
  1. 逐條更新
     update user_item set status=? where id=? and user_id=?
  2. 批次迴圈重複第一步驟和第二步驟即可

推薦學習:《

MySQL影片教學

以上是一文詳解MySQL怎麼批量更新死鎖的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除