软件信息网 移动端开发 数据库死锁场景分析

数据库死锁场景分析

实际业务场景

在我们使用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');

检测到死锁

 具体步骤

步骤一

事务一

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

数据库死锁场景分析插图

 

 

 

步骤二

事务二

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

数据库死锁场景分析插图1

 

 

 

步骤三

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

数据库死锁场景分析插图2

 

 

 

步骤四

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

数据库死锁场景分析插图3

解决方案

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

select id from 业务表  where bussinessid=123;

如果存在,

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

insert into 业务表

作者: 软件定制开发

李铁牛,一直致力于企业客户软件定制开发,计算机专业毕业后,一直从事于互联网产品开发到现在。系统开发,系统源码:15889726201
上一篇
下一篇
联系我们

联系我们

15889726201

在线咨询: QQ交谈

邮箱: 187395037@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部