加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、容器安全、数据加密、云日志、云数据迁移!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

如何批量更新死锁在msyql中

发布时间:2023-06-28 12:00:43 所属栏目:MySql教程 来源:互联网
导读:   这篇“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语句会执行以下步骤:
 
  由于用到了非主键索引,首先需要获取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=?
 
  批量循环重复第一步和第二步即可
 

(编辑:晋中站长网)

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

    推荐文章