首页 > 数据库 >MySQL 间隙锁导致的死锁场景分析

MySQL 间隙锁导致的死锁场景分析

时间:2022-12-01 15:33:08浏览次数:40  
标签:index 事务 name 间隙 死锁 MySQL id

实际业务场景

在我们使用mysql的时候,如果不注意间隙锁容易引起死锁,最近分析一个业务场景就是间隙锁导致的死锁,业务抽象如下:

系统有一个批量新增业务资源的功能,实现逻辑如下(businnessid为非唯一索引):

update 业务表 set isdeleted=1 where bussinessid=123;

insert into 业务表

在并发场景下,以上逻辑产生了死锁。

以下为死锁具体分析以及还原死锁产生过程,最后给出解决方案。

创建一张表

CREATE TABLE `lock_demo` (

`id` INT NOT NULL AUTO_INCREMENT,

`index` INT NOT NULL,

`name` VARCHAR(50) NULL DEFAULT NULL,

PRIMARY KEY (`id`),

INDEX `index` (`index`)

)

COLLATE='utf8mb4_0900_ai_ci'

ENGINE=InnoDB

;

死锁演示

事务一

事务二

update lock_demo set name='a' where index=1;

 

 

update lock_demo set name='a' where index=2; 未卡住,间隙锁之间不冲突

insert into lock_demo(id,`index`,name)values(1,1,'1');

卡住,被事务二的间隙锁锁住

 

 

insert into lock_demo(id,`index`,name)values(2,2,'2');

检测到死锁

 具体步骤

步骤一

事务一

先更新一条记录(不存在),不提交。

 

 

 

 

步骤二

事务二

更新一条记录(不存在),不提交。

 

 

 

 

步骤三

事务一,执行一条新增语句,被事务二的间隙锁锁住

 

 

 

 

步骤四

事务二,执行一条新增语句,被事务一的间隙锁锁住,系统检测到死锁

 

解决方案

对于以上的业务,可以改写sql避免死锁

select id from 业务表  where bussinessid=123;

如果存在,

update 业务表 set isdeleted=1 where id in (xxx);

insert into 业务表

 

标签:index,事务,name,间隙,死锁,MySQL,id
From: https://www.cnblogs.com/wangchaozhi/p/16941432.html

相关文章

  • MySQL数据库-数据完整性-笔记
    数据完整性一个数据库就是一个完整的业务单元,可以包含多张表,数据被存储在表中在表中为了更加准确的存储数据,保证数据的正确有效,可以在创建表的时候,为表添加一些强制性的验证......
  • MongoDB和mysql的区别
    一.什么是MongoDBMongoDB是一个基于分布式文件存储的数据库。由C++语言编写,是一个开源数据库系统。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一......
  • MySQL数据库-安装-笔记
    1.服务器端安装安装服务器端:在终端中输入如下命令,回车后,然后按照提示输入sudoapt-getinstallmysql-server当前使用的ubuntu镜像中已经安装好了mysql服务器端,无需再安装,并......
  • MySQL数据库-Navicat图形界面工具操作-笔记
    1.Navicat连接打开navicat,点击工具栏的“连接”,选择“mysql”,弹出窗口如下图在弹出的窗口中填写名称、主机ip、端口、用户名、密码,如下图密码为mysql点击确定,在左侧栏会看到......
  • Mysql昨天,上个月条件查询
    1.查询昨日数据SELECT*FROMtestWHEREDATEDIFF(DATE_FORMAT(NOW(),'%Y%m%d'),DATE_FORMAT(created_time,'%Y%m%d'))=12.查询上月数据SELECT*FROMtestWHERE......
  • MYSQL 全文检索
    项目中有个日志表需,需求要对日志内容做模糊匹配,但是考虑到数据量会比较大,用like性能不高。查了一下可以用MYSQL自带的全文检索,并且小测试了一下。创建全文检索字段,只有cha......
  • pymysql.err.InterfaceError: (0, '')
    pymysql.err.InterfaceError:(0,'')背景自动化代码需要坚固开发服和测试服,但是又有一些固定数据(或者说是死数据),无法同时满足开发服和测试服,每次if...else...判断url......
  • 使用Docker恢复Mysql8备份的Data数据 - 诚哥博客
    前段时间公司数据库服务器崩溃启动不起来,经过我初步排查是/home目录挂载不上导致启动不起来,虽然通过注释/etc/fstab中的挂载信息,启动了,但是发现mysql数据有缺失,还好有例行......
  • MySQL数据库的定时备份与还原
    一.MySQL备份1.Cron是Linux的内置服务,可以用以下的方法启动、关闭这个服务:servicecrondstart//启动服务servicecrondstop//关闭服务servicecrondrestart/......
  • 一. 预装MySQL前的准备
    1.硬件标准化帮助公司和运维团队,选择最合适MySQL数据库运行的服务器硬件,从品牌、CPU、MEM、IO设备、网络设备、存储设备等各个层次进行合理建议.而不是上采购人员、......