当前位置: 首页 > news >正文

MySQL之死锁

前言

首先我们先看看死锁产生的四个必要条件:

  • 互斥:一个资源只能被一个进程(事务)使用;
  • 请求与条件保持:一个进程(事务)在等待请求的资源过程中,自身已经占有的资源不可释放;
  • 不剥夺条件:进程(事务)在运行活跃时候,已经获得的资源未使用完之前,不可强行剥夺;
  • 循环等待条件:若干个进程(事务)形成首尾相接的循环等待关系;

一般来说业务基本上就是对商品进行新增、修改和查询等操作,我们在对商品进行新增操作前,先通过select … for update操作进行查询,然后再进行相应的业务逻辑处理,所以当业务量很大时,就有可能出现死锁。

死锁的出现

环境:InNoDB引擎、可重复度隔离级别
创建表

CREATE TABLE user (
	`id` INT(11) AUTO_INCREMENT,
	`name` VARCHAR(20) DEFAULT NULL,
	`age` INT NOT NULL,
	PRIMARY KEY (`id`)
) ENGINE = INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

插入数据
在这里插入图片描述
在这里插入图片描述
上面的场景,我们看到两个事物的insert into操作都陷入了阻塞等待状态

为什么会出现死锁?

在InnoDB引擎中的可重复读级别中为了解决幻读的问题,引出了next-key锁,是记录锁和间隙锁的结合。
在可重复度级别中普通的select操作是不会加锁的,通过MVCC机制实现快照读。如果想要解决幻读问题,就需要给查询语句加行锁

//加排它锁
begin;
select ... for update;
commit;

//共享锁
begin;
select ... lock in share mode;
commit;

行锁只有在事务提交后才会释放,并不是语句执行完就释放了。
所以上面,当执行完select * from user where id > 23 for update;
通过 **select * from performance_schema.data_locks\G;**查看当前加上的锁是行锁,X(排它锁)类型的间隙锁(GAP),加锁的范围(20, +∞ )
在这里插入图片描述

next-key锁的加锁规则请看MySQL行锁加锁规则。
所以当事务2执行插入语句是,会在插入的间隙获取插入意向锁,插入意向锁和间隙锁会冲突,所以当其他事务持有间隙锁时,需要等待间隙锁释放,但是间隙锁和间隙锁之间可以兼容,因此两个事物的select … for update操作不会冲突。导致另个事务的间隙锁都在等待对方对方事务间隙锁释放,从而造成循环等待,导致死锁。

如何避免死锁?

死锁产生的四个必要条件:互斥、占有且等待、不可强抢占用、循环等待。只要系统发生死锁,这四个条件必然成立,只要打破一个就会解决死锁。
在数据库层面,设计两种打破死锁的循环等待条件来破坏死锁状态:

  • 设置事务等待锁的超时时间:当一个事务死锁时间超过设置的等待时间参数(innodb_lock_wait_timeout)默认是50秒,这个事务发生回滚,释放锁,另一个事务就可以执行了。
  • 开启死锁主动检测:主动检测到死锁发生,主动回滚一个事物,让其它事物得以执行。将参数innodb_deadlock_detect设置为on

从业务的角度来看,插入前进行select为了保证不出现重复订单,当时也可以将不能重复的字段设置为唯一索引列,利用唯一性避免重复出现,但是插入时有可能会抛出异常。

就是这事,散会。

相关文章:

  • 如何快速晋升自动化测试工程师,10年软测工程师分享的一些经验~
  • 基于k8s搭建部署Nexus服务
  • 处理机调度【操作系统学习笔记】
  • 开源SPL,WebService/Restful广泛应用于程序间通讯,如微服务、数据交换、公共或私有的数据服务等。
  • 炔基聚乙二醇巯基 Alkyne-PEG-SH 炔基PEG硫醇
  • 写作纠错?用机器学习实现单词拼写修正器(附Python代码)
  • 【DjangoDRF+缓存 五万字总结】预计在2022.11月份会再次进行更新
  • 猿创征文|实战开发openGauss DataStudio的sql联想结构
  • VMware创建Linux虚拟机之(三)Hadoop安装与配置及搭建集群
  • 在halcon中使用模板匹配助手进行定位真的很好用!!!
  • 青少年python系列 7.函数
  • python入门——m个位置,每个位置有n种可能,求所有排列结果
  • C | 妙用异或
  • 采用uni-app开发的多端圈子社区论坛系统
  • Java语言特点
  • 深入了解以太坊
  • 【Amaple教程】5. 插件
  • 【React系列】如何构建React应用程序
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • Django 博客开发教程 16 - 统计文章阅读量
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • es6
  • October CMS - 快速入门 9 Images And Galleries
  • Python - 闭包Closure
  • spark本地环境的搭建到运行第一个spark程序
  • Spring Cloud中负载均衡器概览
  • tab.js分享及浏览器兼容性问题汇总
  • Vue.js-Day01
  • 安卓应用性能调试和优化经验分享
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 复习Javascript专题(四):js中的深浅拷贝
  • 给github项目添加CI badge
  • 关于extract.autodesk.io的一些说明
  • 机器学习中为什么要做归一化normalization
  • 力扣(LeetCode)357
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 算法-插入排序
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 用Canvas画一棵二叉树
  • 由插件封装引出的一丢丢思考
  • 你对linux中grep命令知道多少?
  • ​Java并发新构件之Exchanger
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #QT(串口助手-界面)
  • (4.10~4.16)
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (一)基于IDEA的JAVA基础10
  • (转)memcache、redis缓存
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • (转)拼包函数及网络封包的异常处理(含代码)