加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL中如何批量更新死锁

发布时间:2023-07-17 14:41:41 所属栏目:MySql教程 来源:
导读:这篇“MySQL如何批量更新死锁”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇&ld
这篇“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语句会执行以下步骤:
 
由于用到了非主键索引,首先需要获取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=?
 
批量循环重复第一步和第二步即可
 
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章