mysql锁知识笔记
发布日期:2021-05-08 12:13:16 浏览次数:16 分类:精选文章

本文共 1515 字,大约阅读时间需要 5 分钟。

MySQL 锁问题知识点整理

在面试中,MySQL锁问题被频繁提及。虽然之前看过相关博客,但内容容易遗忘,因此整理如下MySQL锁相关知识点:


一、存储引擎

MySQL主要有两种存储引擎:MyISAM 和 InnoDB。

  • MyISAM:仅支持表级锁。执行 selectupdatedeleteinsert 等操作时,会自动给表加锁。MyISAM的插入操作支持并发插入,但并发度较低。

  • InnoDB:支持行级锁,是其主要特点。InnoDB的事务和行级锁大幅度提高了多用户并发处理能力。但InnoDB的行锁基于索引,只有通过索引条件检索数据时才会使用行级锁,否则会使用表锁。


二、MySQL 锁类型

MySQL锁分为表锁、行锁和页面锁三种类型,各有特点:

  • 表锁

    • 开销小,加锁快,不会出现死锁。
    • 锁定粒度大,发生锁冲突概率高,并发度最低。
    • 适用于对并发度要求不高的场景。
  • 行锁

    • 开销大,加锁慢,可能出现死锁。
    • 锁定粒度小,发生锁冲突概率最低,并发度最高。
    • 适用于对并发处理要求高的场景。
  • 页面锁

    • 开销和加锁时间介于表锁和行锁之间。
    • 会出现死锁,锁定粒度介于表锁和行锁之间。
    • 并发度一般。

三、表锁

1. 表锁锁模式
  • 表共享读锁(Table Read Lock):允许其他用户读取同一表数据,不会阻塞其他用户的读操作,但会阻塞写操作。
  • 表独占写锁(Table Write Lock):只允许持有锁的用户对表进行写操作,其他用户的读或写操作会被阻塞。
2. 加表锁
  • MyISAM引擎

    • select 操作会自动加读锁。
    • updatedeleteinsert 操作会自动加写锁。
    • 不需要用户显式使用 lock table 命令。
  • 显式加锁:用于模拟事务操作,实现对某一时间点多个表的一致性读取。

3. 并发插入
  • MyISAM支持并发插入,通过 concurrent_insert 控制。

四、行锁

1. InnoDB锁定模式及实现机制
  • InnoDB的行级锁分为共享锁和排他锁,且在锁定过程中会使用意向锁(共享意向锁 IS 和排他意向锁 IX)。
  • 锁定兼容性:如果一个事务需要的锁与当前锁兼容,则授予锁;否则等待锁释放。
2. 行锁实现方式
  • 行锁是通过索引项加锁实现的,只有通过索引条件检索数据时才会使用行级锁。
  • 如果没有通过索引检索数据,InnoDB会使用表锁。
  • 不同的事务可以通过不同的索引锁定不同的行,但相同索引键会导致锁冲突。
3. 间隙锁(Next-Key锁)
  • 当使用范围条件(如 betweenlike)检索数据时,InnoDB会对符合条件的已有记录和不存在的记录(间隙)加锁。
  • 间隙锁会影响查询性能,需谨慎使用。
4. 死锁
  • MyISAM表锁是 deadlock-free 的,因其所有锁都是在一次操作中获得。
  • InnoDB可能产生死锁,尤其是在多个事务需要相互等待对方持有的锁。
  • InnoDB检测死锁时,会回滚较小的事务以避免死锁。
5. 行锁优化建议
  • 尽量通过索引检索数据,避免使用全表扫描。
  • 合理设计索引,减少锁定范围。
  • 减少事务大小,避免长时间锁定。
  • 避免基于范围的过滤条件,减少间隙锁影响。

五、悲观锁与乐观锁

  • 悲观锁

    • MyISAM表锁都是悲观锁,InnoDB默认为悲观锁。
    • 悲观锁事后检查,锁定粒度大,容易产生死锁。
  • 乐观锁

    • 需要自定义实现,如Java中的 ReentrantLockSynchronized
    • 乐观锁通过乐观性检查(如 compare-and-set)避免死锁,锁定粒度小。

通过以上知识点的理解和应用,可以更好地应对MySQL锁相关问题,在实际项目中实现高并发处理。

上一篇:单例模式
下一篇:mybatis-plus通用mapper调用报错:Invalid bound statement

发表评论

最新留言

感谢大佬
[***.8.128.20]2025年04月30日 22时55分49秒