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

数据库的死锁相关(一)

目录

前言

一、什么死锁

二、产生死锁的必要条件

三、死锁发生的具体位置和场景

1. 数据行级别死锁(最常见)

2. 表级别死锁

3. 索引间隙锁死锁(InnoDB特有)

4. 外键约束死锁

5. 元数据锁死锁

6. 内存中的锁结构死锁

7. 分布式系统死锁

如何定位死锁位置

四、关键点总结


前言

        没有实践就没有发言权,前段时间无聊时,刷到数据库死锁相关的。发现自己对这部分有所空缺,查资料进行总结实践,得出自我观点。


一、什么死锁

        数据库死锁是指两个或多个事务在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,这些事务都将无法继续执行下去。


二、产生死锁的必要条件

1. 互斥条件 (Mutual Exclusion)

  • 资源一次只能由一个事务独占使用
  • 例如:某一行数据在同一时间只能被一个事务锁定

2. 占有并等待 (Hold and Wait)

  • 事务已经持有至少一个资源,同时又在等待获取其他事务持有的资源
  • 例如:事务A持有记录1的锁,同时请求记录2的锁

3. 非抢占条件 (No Preemption)

  • 已分配给事务的资源不能被强制剥夺,只能由持有者显式释放
  • 数据库中的锁通常不能强行从另一个事务中夺取

4. 循环等待 (Circular Wait)

  • 存在一个事务等待环路,每个事务都在等待下一个事务所持有的资源
  •  例如:T1等待T2,T2等待T3,T3等待T1

三、死锁发生的具体位置和场景

1. 数据行级别死锁(最常见)

发生位置

  • 表中的特定数据行

  • 索引记录(包括主键索引和二级索引)

典型场景

-- 事务A
UPDATE users SET balance = balance - 100 WHERE id = 1; -- 锁住id=1的行
UPDATE users SET balance = balance + 100 WHERE id = 2; -- 尝试锁住id=2的行(等待)-- 事务B
UPDATE users SET balance = balance - 50 WHERE id = 2; -- 锁住id=2的行
UPDATE users SET balance = balance + 50 WHERE id = 1; -- 尝试锁住id=1的行(等待)

2. 表级别死锁

发生位置

  • 整个数据表

  • 表锁(如MySQL的MyISAM引擎)

典型场景

-- 事务A
LOCK TABLE orders WRITE; -- 获取orders表锁
-- 尝试获取customers表锁(等待)-- 事务B
LOCK TABLE customers WRITE; -- 获取customers表锁
-- 尝试获取orders表锁(等待)

3. 索引间隙锁死锁(InnoDB特有)

发生位置

  • 索引记录之间的间隙

  • 不存在的记录范围

典型场景

-- 事务A
SELECT * FROM accounts WHERE id > 100 FOR UPDATE; -- 锁住id>100的间隙
-- 事务B同时执行
SELECT * FROM accounts WHERE id < 50 FOR UPDATE;  -- 锁住id<50的间隙
-- 当两个事务尝试向对方锁定的间隙插入数据时可能死锁

4. 外键约束死锁

发生位置

  • 主表和从表的外键关系处

  • 级联更新/删除操作时

典型场景

-- 事务A
UPDATE parent_table SET id = 2 WHERE id = 1; -- 需要检查/锁定子表外键
-- 事务B同时
UPDATE child_table SET parent_id = 3 WHERE parent_id = 2; -- 需要检查/锁定父表

5. 元数据锁死锁

发生位置

  • 数据字典(表结构)

  • 在执行DDL和DML并发时

典型场景

-- 事务A
BEGIN;
SELECT * FROM products; -- 获取元数据读锁
-- 事务B同时执行
ALTER TABLE products ADD COLUMN description TEXT; -- 需要元数据写锁(等待)
-- 如果事务A后续尝试执行需要元数据升级的操作可能死锁

6. 内存中的锁结构死锁

发生位置

  • 数据库内部锁管理结构

  • 缓冲池中的页锁

典型场景

  • 多个事务竞争同一内存页的访问权限

  • 锁管理数据结构本身的并发控制问题


7. 分布式系统死锁

发生位置

  • 跨数据库节点

  • 跨不同服务/微服务

典型场景

节点A的服务1: 锁定资源X,请求节点B的资源Y
节点B的服务2: 锁定资源Y,请求节点A的资源X

四、如何定位死锁位置

1. MySQL

SHOW ENGINE INNODB STATUS\G;
-- 查看"LATEST DETECTED DEADLOCK"部分

2. SQL Server

SELECT * FROM sys.dm_tran_locks;
-- 查看死锁图

3. Oracle

SELECT * FROM v$locked_object;
SELECT * FROM dba_blockers;

五、关键点总结

  1. 死锁最常发生在行级锁和间隙锁上

  2. 不同数据库引擎的死锁热点位置不同(如InnoDB主要在索引记录)

  3. 死锁不仅发生在数据上,也可能发生在系统内部资源上

  4. 分布式环境死锁范围更广,更难检测


那要如何解决上述问题请跳转:数据库的死锁相关(二)

http://www.xdnf.cn/news/3443.html

相关文章:

  • 动态规划 -- 子数组问题
  • nginx 配置要领
  • 客户服务升级:智能语音外呼系统在多领域的场景应用解析
  • 大模型时代的新燃料:大规模拟真多风格语音合成数据集
  • 面经很简单的
  • 机器学习_KNN算法
  • 【SpringBoot】基于mybatisPlus的博客管理系统(2)
  • 汽车电子 专栏文章汇总
  • python+echart绘制一个听力图
  • 常用电机类型及其特点对比
  • 如何用fiddler进行弱网测试(工作常用篇)
  • sd webui 安装插件sd-webui-EasyPhoto依赖安装失败解决办法
  • 基于深度强化学习训练一个会走迷宫的ai
  • java之Integer、Double自动拆装箱比较,踩坑值int和Integer比较之空指针异常
  • WPF之TextBox控件详解
  • 第八节:目录操作
  • 二叉树的路径总和问题(递归遍历,回溯算法)
  • 如何理解神经网络训练的循环过程
  • 产品月报|睿本云4月产品功能迭代
  • MS31860T——8 通道串行接口低边驱动器
  • 制造业行业ERP软件部署全流程指南:从选型到维护,怎么做?
  • 多线程爬虫中实现线程安全的MySQL连接池
  • Java程序员如何设计一个高并发系统?
  • 基于MCP协议实现一个智能审核流程
  • 虚拟内存笔记(一)
  • AVPro Video加载视频文件并播放,可指定视频文件的位置、路径等参数
  • 运用ESS(弹性伸缩)技术实现服务能力的纵向扩展
  • foxmail时不时发送不了邮件问题定位解决过程
  • 苍穹外卖11
  • Windows查看和修改IP,IP互相ping通