首页 > 数据库 >谈一谈数据库中的死锁问题

谈一谈数据库中的死锁问题

时间:2024-09-13 10:49:20浏览次数:10  
标签:谈一谈 行锁 检测 数据库 死锁 线程 等待 资源

文章目录

本篇文章是基于《MySQL45讲》来写的个人理解与感悟。

死锁是什么?

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

比如:两个线程A、B各自持有一个无法共享的资源,并且他们都需要获取对方现在持有的资源才能进行下一步,但是他们又必须等对方释放了才能去获取,于是A等待B,B也在等待A。如此这般,死锁就产生了。

而对于MySQL,如果只支持到表锁的引擎,同一张表上任何时刻只能有一个更新在执行,这就会影响到业务并发度。也就意味着如果我们对某一个表进行修改的时候这张表就会被锁住,从而影响效率。因此有了行锁。
而行锁是遵循两阶段提交协议的,这也就意味着虽然我们可以主动开启行锁,但是只有事务提交的时候行锁才会被释放。那么这就容易产生了死锁。

死锁的四个必要条件

互斥条件:指多个线程不能同时使用同一个资源。
在这里插入图片描述

请求与保持条件: 当线程 A 已经持有了资源 1,又想申请资源 2,而资源 2 已经被线程 C 持有了,所以线程 A 就会处于等待状态,但是线程 A 在等待资源 2 的同时并不会释放自己已经持有的资源 1。
在这里插入图片描述

不可剥夺条件:当线程已经持有了资源 ,在自己使用完之前不能被其他线程获取,线程 B 如果也想使用此资源,则只能在线程 A 使用完并释放后才能获取。
在这里插入图片描述

换路等待条件:在死锁发生的时候,两个线程获取资源的顺序构成了环形链。
在这里插入图片描述

图片来源:小林coding

那么我们接下来看一下死锁的例子:

比方说,此时有两个用户去电影院购票,然后购票其实是有三个步骤。

  1. 从顾客A、B账户余额中扣除电影票价;

  2. 给影院的账户余额增加这张电影票价;

  3. 记录一条交易日志。

因为要保证数据库完整性,所以会用到事务。假设此时我们两个用户都去购票,然后因为增加电影院的账户余额的这个动作两个用户要需要进行,这个时候会需要行锁去操作增加,然后又因为行锁其实是必须要在事务提交之后才会释放。

所以一旦某个操作阻塞住了,那么就会产生死锁。

而且有些电影院可以有预售秒杀的那种活动嘛,这样的话,一旦阻塞住,那么cpu会飙升,最后导致数据库挂了。

避免死锁的策略

  1. 超时等待:也就是等待一定时间,如果没有获取到锁那么线程就自动退出,但是等待的时间很不好把握,所以一般用第二种方法。

  2. 死锁检测:也就是说,发起死锁检测,然后查看是否发生死锁【是否出现循环等待】,一旦发生就会回滚这个死锁链条的某个事务,这样的话就让其他事务可以继续执行。

但是死锁检测也不是万能的,比如还是出现了上面一样的情况【对同一行记录进行更新】,假设同时有一千条并发线程同时去操作,那么死锁检测是O(N)的,所以就回去检查完1000个线程之后才检测完,而在这个期间会占用大量的CPU资源的,所以就会看到虽然CPU占用资源很高,但是处理的效率缺差强人意。

那么如何解决这种热点行更新操作导致的问题呢?
  1. 抓住矛盾的主要方面,也就是说如果你可以确定这个业务不会发生死锁问题,就可以把死锁检测关掉。

但是这种操作本身带有一定的风险,因为业务设计的时候一般不会把死锁当做一个严重错误,毕竟出现死锁了,就回滚,然后通过业务重试一般就没问题了,这是业务无损的。而关掉死锁检测意味着可能会出现大量的超时,这是业务有损的。

  2. 控制并发度
在这里插入图片描述

标签:谈一谈,行锁,检测,数据库,死锁,线程,等待,资源
From: https://blog.csdn.net/WLKQNYJY_SHT/article/details/142111918

相关文章

  • 民宿预定|基于springboot+vue的民宿在线预定平台系统(源码+数据库+文档)
    民宿在线预定平台目录基于springboot+vue的民宿在线预定平台系统一、前言二、系统设计三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风者计划专家博主,CSD......
  • 数据库———事务及bug的解决
    一:事务1:场景引入张三在银行账户中存有1000元,李四存有500元,这时张三要给李四支付500元,执行sql语句①:updateaccountsetbalance=balance-500wherename='张三';②:updateaccountsetbalance=balance+500wherename='李四';想象一下,如果在sql语句①执行完......
  • 【含文档】基于Springboot+Vue的同城上门喂遛宠物系统的设计与实现(含源码数据库)
    1.开发环境开发系统:Windows10/11架构模式:MVC/前后端分离JDK版本:JavaJDK1.8开发工具:IDEA数据库版本:mysql5.7或8.0数据库可视化工具:navicat服务器:SpringBoot自带apachetomcat主要技术:Java,Springboot,mybatis,mysql,vue2.视频演示地址3.功能系统中......
  • 【含文档】基于Springboot+Vue的大学生计算机基础网络教学系统管理(含源码数据库)
    1.开发环境开发系统:Windows10/11架构模式:MVC/前后端分离JDK版本:JavaJDK1.8开发工具:IDEA数据库版本:mysql5.7或8.0数据库可视化工具:navicat服务器:SpringBoot自带apachetomcat主要技术:Java,Springboot,mybatis,mysql,vue2.视频演示地址3.功能这个系......
  • PbootCMS无缝sqlite数据库转mysql数据库
    将PbootCMS的SQLite数据库无缝转换为MySQL数据库,可以遵循以下步骤。请注意,这里所说的“无缝”转换是指尽可能减少数据丢失和格式错误,但仍然需要确保转换后的数据能够正常工作。以下是详细的转换步骤:1.导出SQLite数据库打开SQLiteStudio或类似工具:使用SQLiteStud......
  • 未检测到您服务器环境的sqlite3数据库扩展,请检查php.ini中是否已经开启该扩展
    当你遇到“未检测到您服务器环境的sqlite3数据库扩展,请检查php.ini中是否已经开启该扩展”的提示时,这表明PHP当前的安装环境中没有启用SQLite3支持。SQLite3是一个轻量级的嵌入式数据库引擎,它通常用于不需要完整服务器端数据库解决方案的应用场景。解决方法1.检查 ph......
  • 如何在删除ibdata1和ib_logfile的情况下恢复MySQL数据库
    昨天,有个朋友对公司内部使用的一个MySQL实例开启binlog,但是在启动的过程中失败了(他也没提,为何会失败),在启动失败后,他删除了ibdata1和ib_logfile,后来,能正常启动了,但所有的表通过showtables能看到,但是select的过程中却报“Tabledoesn'texist”。于是,建议他试试可传输表空间。同......
  • 数据库tips17
    (十)、约束及索引类型约束的作用是为了防止可预见的错误的数据进入数据库中,是保障数据一致性的一种机制。UNIQUE约束是列级约束,表示关系中的记录在该列上的取值不重复。索引是通过建立索引列上的索引表,索引表中的査找项是索引列上的所有值的排序或散列(目的是为了快速查找),索引表中......
  • 1765asp.net古镇旅游网站VS开发sqlserver数据库web结构c#编程web网页设计
    博主介绍:专注于Java.net phpphython 小程序等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作☆☆☆精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟我的博客空间发布了1000+毕设题目方便大家学习使用感兴趣的可以先收藏起来,还有大家在......
  • Springboot点餐系统jl9ml(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、项目背景与意义随着信息技术的飞速发展和餐饮行业的日益繁荣,传统的点餐方式已难以满足现代消费者对于便捷性、高效性和个性化服务的需求。因此......