MySql锁机制

1. 表级锁

意向锁解决了一个表加了行锁和读锁的冲突问题

2.行级锁

3.MVCC实现原理

MySQL 锁机制详解:从原理到实战,一文搞懂行锁、表锁、意向锁

一、为什么要学 MySQL 锁?

并发场景下,多个事务同时操作数据库,会出现脏读、不可重复读、幻读 ,还会引发更新丢失、数据错乱。就是 MySQL 解决并发竞争、保证数据隔离性与一致性的核心机制。

简单理解:锁就是数据库给数据加的 "权限门禁",有人在用,别人就得排队或禁止操作

二、MySQL 锁的整体分类

粒度分:

  1. 表级锁:锁住整张表
  2. 行级锁:锁住某一行记录
  3. 页级锁:锁住数据页(MyISAM 不支持,InnoDB 少见)

类型分:

  • 共享锁(S 锁、读锁):可读不可改,多人可同时加 S 锁
  • 排他锁(X 锁、写锁):不可读也不可改,独占

三、表级锁(MyISAM 默认)

1. 特点

  • 粒度最大,开销小,加锁快
  • 不会死锁
  • 并发极差,一锁锁整张表

2. 分类

  • 表共享读锁:所有人可以读,不能写
  • 表排他写锁:自己可读写,其他人啥都不能做

3. 适用场景

查询多、更新少的业务;MyISAM 引擎专用。

缺点:只要有一个事务写表,所有其他事务都阻塞,高并发完全扛不住。

四、行级锁(InnoDB 默认核心)

InnoDB 支持事务、支持行锁,也是业务开发最常用的锁。

1. 特点

  • 粒度最小,只锁一行
  • 加锁慢、开销大
  • 会产生死锁
  • 并发性能极高

2. 行锁两大类型

  • 行共享锁 Sselect ... lock in share mode
  • 行排他锁 Xselect ... for update / 增删改默认加 X 锁

3 重点:行锁生效前提

必须走索引! 如果没走索引,MySQL 会降级为表锁,直接锁整张表,并发直接废掉。

五、意向锁(InnoDB 自动加)

很多人看不懂意向锁,其实很简单:意向锁是表级辅助锁,标记 "我要在表里面加行锁了",用来快速判断表是否有行锁冲突,不用遍历每一行。

两种:

  1. 意向共享 IS:事务打算给行加 S 锁
  2. 意向排他 IX:事务打算给行加 X 锁

兼容性口诀:

  • IS 和 IS、IX 都兼容
  • IX 和 S、X 基本互斥,避免表锁与行锁冲突

意向锁人工不用管,InnoDB 自动维护,只需要懂原理即可。

六、快照读 & 当前读(锁的底层关键)

1. 快照读

不加锁,读历史版本数据 ,基于 MVCC普通 select * from table 就是快照读,无锁、快、不阻塞。

2. 当前读

读取最新数据,加行锁包括:

  • insert、update、delete
  • select ... for update
  • select ... lock in share mode

七、三种经典锁问题

1. 脏读

事务读到了其他事务未提交的数据。

2. 不可重复读

同一事务内,两次查询同一行,结果不一样(被其他事务修改提交)。

3. 幻读

同一事务范围查询,前后行数不一样,其他事务插入 / 删除了新数据。

InnoDB 通过 Next-Key 临键锁 解决幻读。

八、临键锁 Next-Key(重点面试必问)

InnoDB 默认行锁算法,三合一:记录锁 + 间隙锁 + 临键锁

  • 记录锁:锁当前存在的行
  • 间隙锁:锁两条数据中间的空隙,禁止插入
  • 临键锁:锁住索引左开右闭区间,彻底解决幻读

九、死锁产生与避免

1. 死锁条件

  • 互斥
  • 持有并等待
  • 不可剥夺
  • 循环等待

2. 如何避免死锁

  1. 统一 SQL 执行顺序
  2. 尽量按主键 / 索引加锁
  3. 事务尽量短小,尽早提交
  4. 避免长事务

十、开发实战避坑总结

  1. 能用 InnoDB 别用 MyISAM,高并发必须行锁
  2. 行锁一定要走索引,否则降级表锁
  3. 普通查询用快照读,别乱用 for update
  4. 批量更新尽量缩小范围,减少锁范围
  5. 事务别写太长,防止锁持有时间过久
  6. 理解 MVCC + 临键锁,就能吃透 MySQL 并发
相关推荐
不正经学生9 分钟前
C语言预处理详解:编译器真正动手之前的那些事
c语言·开发语言·算法·面试·bug
门思科技19 分钟前
LoRaWAN 设备类别:Class A、B、C 对比与选型指南
c语言·开发语言·php
恋恋西风3 小时前
C++ 理解 std::thread 在单核和多核上的行为差异
开发语言·c++
学长毕业设计3 小时前
基于SpringBoot的公益基金管理系统(源码+文档+讲解视频)
java·spring boot·后端
Brilliantwxx3 小时前
【Linux】 进程(9)程序与进程地址空间(基础+进阶+面试题)
linux·运维·服务器·开发语言·c++
东小西3 小时前
【SAA实战】第 3 篇 · 工具调用全攻略:把业务能力交给 Agent 自己调度
java·后端·spring
东小西3 小时前
【SAA实战】第 4 篇 · Agent 短期记忆:saver 让 Agent 跨轮记得住(threadId 隔离)
java·后端·spring
许彰午3 小时前
22-DataCenter报文序列化
java·低代码·架构·状态模式
2601_962065254 小时前
[MySQL] SQL优化之性能分析
java·sql·mysql
BizzZ_4 小时前
C++(22)——类型转换和IO流
开发语言·c++