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

MySQL 专题(三):事务与锁机制深度解析

MySQL 专题(三):事务与锁机制深度解析

在这里插入图片描述

在 MySQL 的世界里,事务(Transaction)和锁(Lock) 就像交通规则和红绿灯,保证了数据库的并发访问不会陷入混乱。

很多初学者只知道 BEGIN; COMMIT; ROLLBACK;,但在实际项目里,理解事务和锁机制,能帮助我们解决脏读、幻读、死锁等复杂问题。


一、事务的四大特性(ACID)

事务(Transaction)是一组要么全部成功、要么全部失败的操作,核心有 ACID 四大特性

  1. 原子性(Atomicity)

    • 事务中的操作要么全部成功,要么全部失败。
    • 实现方式:Undo Log(回滚日志)。
  2. 一致性(Consistency)

    • 数据在事务前后必须保持一致状态。
    • 比如转账 100 元,A 扣 100,B 加 100,事务失败则必须两边都不变。
  3. 隔离性(Isolation)

    • 多个事务同时执行时,互不干扰。
    • 实现方式:锁 + MVCC
  4. 持久性(Durability)

    • 一旦事务提交,数据必须落盘,即使宕机也不能丢。
    • 实现方式:Redo Log(重做日志)。

👉 Undo Log + Redo Log = 数据安全双保险


二、事务隔离级别

SQL 标准定义了四种隔离级别,用来解决并发读写时可能出现的问题:

隔离级别脏读 (Dirty Read)不可重复读 (Non-repeatable Read)幻读 (Phantom Read)性能
读未提交 (RU)✅ 可能✅ 可能✅ 可能
读已提交 (RC)❌ 避免✅ 可能✅ 可能
可重复读 (RR)❌ 避免❌ 避免✅ 可能较低
串行化 (Serializable)❌ 避免❌ 避免❌ 避免最低

MySQL 默认隔离级别:可重复读(RR)

  • 使用 MVCC(多版本并发控制) 来避免不可重复读。
  • 幻读问题则通过 间隙锁(Gap Lock) 来解决。

三、锁机制解析

在事务的实现过程中,锁是核心工具。MySQL 提供了 行锁、表锁、意向锁、间隙锁 等多种类型。

1. 行锁(Record Lock)

  • 针对某一行数据加锁。
  • 例如:
SELECT * FROM user WHERE id=1 FOR UPDATE;

👉 锁住 id=1 这一行。


2. 间隙锁(Gap Lock)

  • 锁住索引区间,防止“幻读”。
  • 示例:
SELECT * FROM user WHERE age BETWEEN 20 AND 30 FOR UPDATE;

👉 除了锁住已存在的记录,还会锁住 20~30 区间,阻止插入新数据。


3. 临键锁(Next-Key Lock)

  • 行锁 + 间隙锁 的结合。
  • 保证同一事务中多次读取结果一致,避免幻读。

4. 表锁(Table Lock)

  • 粒度大,一般在 ALTER TABLE 等结构变更时使用。

5. 意向锁(Intention Lock)

  • 解决 表锁与行锁冲突检测效率低 的问题。
  • 例如:一个事务在表上加了行锁,另一个事务要加表锁,MySQL 只需要检查意向锁而不是逐行检查。

四、事务并发问题案例

1. 脏读(Dirty Read)

事务 A 修改了数据但未提交,事务 B 就读取到了修改后的值,如果 A 回滚,B 读到的数据就是脏的。

👉 解决:使用 读已提交(RC) 或更高隔离级别。


2. 不可重复读(Non-repeatable Read)

事务 A 读取某行数据,事务 B 修改并提交了该行,事务 A 再次读取,发现数据不同。

👉 解决:使用 可重复读(RR)


3. 幻读(Phantom Read)

事务 A 读取 age > 20 的用户列表,事务 B 插入了一个新用户 age=21 并提交。
事务 A 再次读取时,结果多了一条“幻影”数据。

👉 解决:RR + 间隙锁串行化隔离级别


五、死锁与解决

死锁产生场景

  • 事务 A 锁住了行 X,请求行 Y;
  • 事务 B 锁住了行 Y,请求行 X;
    👉 双方互相等待,形成死锁。

解决策略

  1. 超时回滚:InnoDB 默认检测死锁并回滚一个事务。

  2. 避免死锁的方法

    • 按相同顺序访问表和行;
    • 事务尽量小,减少锁持有时间;
    • 避免长事务。

六、实践建议

  1. 尽量使用短事务,减少锁时间,降低死锁概率。
  2. 合理选择隔离级别:大多数场景用 RC 或 RR 就够了。
  3. 建索引优化锁范围:没有索引时,MySQL 会升级为 全表锁,性能急剧下降。
  4. 监控死锁:通过 SHOW ENGINE INNODB STATUS\G 查看死锁日志。

七、总结

  1. 事务 ACID 保证了数据的安全性和一致性。
  2. 隔离级别 决定了并发访问的效果与性能平衡。
  3. 锁机制(行锁、间隙锁、意向锁等) 是 MySQL 保证并发一致性的核心。
  4. 死锁不可避免,但可以通过设计和索引优化来降低发生概率。

👉 一句话总结:
事务和锁就像交通规则与红绿灯,理解它们,才能让 MySQL 在高并发下依然保持秩序和高性能。


http://www.dtcms.com/a/388816.html

相关文章:

  • 使用BLIP训练自己的数据集(图文描述)
  • Geoserver修行记--在geoserver中如何复制某个图层组内容
  • DBG数据库透明加密网关:SQLServer应用免改造的安全防护方案,不限制开发语言的加密网关
  • 不同上位开发语言、PLC下位平台、工业协议与操作系统平台下的数据类型通用性与差异性详解
  • 【入门篇|第二篇】从零实现选择、冒泡、插入排序(含对数器)
  • javaweb Servlet基本介绍及开发流程
  • MySQL MHA高可用
  • 整体设计 逻辑拆解之2 实现骨架:一元谓词+ CNN的谓词系统
  • SpEL(Spring Expression Language)学习笔记
  • Java 字节码进阶3:面向对象多态在字节码层面的原理?
  • Tensor :核心概念、常用函数与避坑指南
  • 机器学习实战·第四章 训练模型(1)
  • 一次因表单默认提交导致的白屏排查记录
  • Linux:io_uring
  • 《第九课——C语言判断:从Java的“文明裁决“到C的“原始决斗“——if/else的生死擂台与switch的轮盘赌局》
  • 学习日报|Spring 全局异常与自定义异常拦截器执行顺序问题及解决
  • Spring Boot 参数处理
  • Debian系统基本介绍:新手入门指南
  • Spring Security 框架
  • Qt QPercentBarSeries详解
  • RTT操作系统(3)
  • DNS服务管理
  • IDA Pro配置与笔记
  • 虚函数表在单继承与多继承中的实现机制
  • 矿石生成(1)
  • Linux 线程的概念
  • Unity学习之资源管理(Resources、AssetDatabase、AssetBundle、Addressable)
  • LG P5138 fibonacci Solution
  • 删除UCPD监控服务或者监控驱动
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(33):文法運用第10回1+(考え方14)