【MySQL】死锁-Deadlock found when trying to get lock; try restarting transaction

错误:Deadlock found when trying to get lock; try restarting transaction

1.场景:

建表语句:

CREATE TABLE `aaa` (
  `id` bigint(20) NOT NULL COMMENT '主键',
  `schs_id` bigint(20) NOT NULL COMMENT '',
  `sch_id` bigint(20) NOT NULL COMMENT '',
  `rsp_status` bit(1) NOT NULL DEFAULT b'1' COMMENT '1 成功   0 失败',
  PRIMARY KEY (`id`),
  KEY `sch_id_status` (`sch_id`,`rsp_status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='';

并发执行insert、update操作。

  • update aaa SET rsp_status=0 where id in( SELECT a.id FROM ( select id from aaa as A where A.sch_id=462894582813392896 order by A.id limit 0 ,34 ) a )
  • insert into aaa value();
    在这里插入图片描述

2.Mysql锁类型分析

MySQL有三种锁的级别:页级、表级、行级,这个地方遇到的问题是来自于行级锁,所以重点说一下。

类型特性
表级锁 (table-level locking)开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁 (row-level locking)开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁 (page-level locking)开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

行级锁在使用的时候并不是直接锁掉这行记录,而是锁索引
如果一条sql用到了主键索引(mysql主键自带索引),mysql会锁住主键索引;
如果一条sql操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引.

在这里插入图片描述
原因:
update 语句中使用到了sch_id非主键索引,则根据上述介绍,update操作会锁住sch_id索引和id索引(有点猜测成分)。这样进行insert的时候,sch_id索引被锁住,无法插入数据更新索引,导致死锁。

解决方案:
删除’sch_id_status’索引,执行表级锁。

https://blog.csdn.net/qq_44240587/article/details/108400666

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值