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 并发
相关推荐
花里胡哨的菜只因2 小时前
IDEA 编译 Maven 项目报 Malformed \uxxxx encoding
java·maven·intellij-idea
此生决int2 小时前
C++快速上手java备战期末考——初识java
java·c++·期末复习
Jing_jing_X2 小时前
通义灵码Lingma IDE:解决你的提示词焦虑
java·ide·ai
计算机安禾2 小时前
【c++面向对象编程】第13篇:继承(三):同名隐藏与作用域覆盖
开发语言·c++·iphone
ch.ju2 小时前
Java Programming Chapter 3——Dynamic acquisition of array
java·开发语言
XS0301062 小时前
Java Web实现简易CRUD操作笔记
java·前端·笔记
TechWayfarer2 小时前
AI的幻觉谁来买单?智能体时代的数据溯源与鉴权
开发语言·python·安全·ai
Str_Null2 小时前
Python 自动线性化 HTML/MD 表格的工程实践(一个读取表格并且提供输出的工具)
开发语言·python·html
Shadow(⊙o⊙)2 小时前
qt内详解信号和槽的基本概念+实例演示
开发语言·前端·c++·qt·学习