2.mysql 锁 并发控制
发布日期:2021-05-08 05:54:26 浏览次数:29 分类:精选文章

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

读写锁与锁机制

读写锁

读锁(共享锁):允许多个读操作并发执行,阻止写操作。

写锁(互斥锁):只允许一个操作执行,阻止其他所有操作。

全局锁

全局锁是数据库层面的锁,作用范围覆盖整个数据库。

数据库备份通常会使用全局锁,确保所有操作都能被锁定,避免数据不一致。
全局锁会阻止任何对数据库的更新操作,确保备份过程的完整性。

表锁

表锁是锁的下一个层次,作用范围是整个表。

显式加锁

LOCK TABLES t_user READ/WRITE; UNLOCK TABLES;
  • 读锁允许其他连接对表进行只读操作。
  • 写锁禁止其他连接对表的读或写操作。
  • 加锁连接在提交事务前只能执行与锁兼容的操作。
  • UNLOCK TABLES 之前,禁止对其他表的读或写操作。

隐式加锁

隐式加锁通常通过事务操作实现。

SELECT * FROM t_user, moneylog;

等价于:

LOCK TABLES t_user READ, moneylog READ; SELECT * FROM t_user, moneylog; UNLOCK TABLES;
  • 查询会自动加锁,插入、更新、删除会自动加写锁。
  • 事务提交或回滚时会自动释放所有锁。
  • 适用于需要高一致性的场景,避免数据不一致。

总结

表锁机制的优点是避免死锁,性能相对较高,但缺点是并发性差,可能导致读饥饿。

适用于读多、写少的场景,且没有锁超时机制时,需通过事务设计避免长时间锁占用。

行锁

行锁是锁的最细粒度,作用范围是单行数据。

显式加锁

InnoDB支持显式加锁:

  • 读锁:SELECT * FROM t_user LOCK IN SHARE MODE;
  • 写锁:SELECT * FROM t_user FOR UPDATE;

隐式加锁

InnoDB默认使用行锁:

  • 对于 UPDATEDELETEINSERT,会自动加写锁。
  • 对于普通 SELECT 语句,不会加锁,但可以显式加锁。
  • 事务提交或回滚时会自动释放锁。

InnoDB行锁实现

InnoDB行锁主要基于索引,以下是关键点:

  • 行锁只在使用索引时生效,否则会退化为表锁。
  • 全表扫描会加表锁。
  • 多个连接操作不同行,但同一索引会互斥。

意向锁

InnoDB引入意向锁解决表锁与行锁兼容性问题。

  • 加行锁时,会在对应表上加意向锁。
  • 意向锁是表锁,用于快速判断是否有行锁或意向锁冲突。
  • 目的在于减少锁冲突,提高并发性能。

间隙锁

InnoDB使用间隙锁解决幻读问题。

  • 范围查询时,加共享或排他锁,会对已存在的行加行锁,未存在的行加间隙锁。
  • 间隙锁会阻塞插入操作,避免数据不一致。
  • 建议避免范围查询导致间隙锁,使用FOR UPDATELIMIT等方式。

死锁处理

InnoDB支持以下死锁处理机制:

  • 死锁避免:通过锁的顺序控制。
  • 死锁检测:通过超时机制。
  • 死锁恢复:回滚写锁的事务,保持最少锁持有时间。

存储引擎锁支持

  • myisam:只支持表锁。
  • InnoDB:支持表锁和行锁,默认使用行锁。
  • 其他存储引擎:根据引擎类型提供不同的锁机制。
上一篇:3.mysql 事务
下一篇:1.mysql逻辑架构

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年05月04日 18时00分58秒