一文详解MySQL怎么批量更新死锁

藏色散人
发布: 2023-04-13 16:32:37
转载
1599 人浏览过

本篇文章给大家带来了关于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上的锁,这样就出现了死锁。

解决方案:

  1. 先获取需要更新的记录的主键
    select id from user_item where user_id=? and item_id=?
    登录后复制
  2. 逐条更新
     update user_item set status=? where id=? and user_id=?
    登录后复制
  3. 批量循环重复第一步和第二步即可

推荐学习:《MySQL视频教程

以上是一文详解MySQL怎么批量更新死锁的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
来源:learnku.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板