MySQL锁等级
MySQL锁的类型
数据库锁的类型主要有:
- 表锁
- 行锁
- 间隙锁
- 临键锁
知识点助记
把数据库比作图书馆,看书就是读数据,借还书就是写数据
- 表锁:就像图书馆闭馆清点。谁也不准进来,谁也不让出去。优点是管理简单,缺点是效率低。
- 行锁:就像读者用个人借书卡锁定了某本具体的书。其他人可以随便看,借还别的书,但是被锁定的这本书,在被归还(事务结束)前
别人不能借走(修改)。 - 间隙锁:图书馆的书架不是连续的,有些书架上是空着的。间隙锁就是锁住这些空位置,禁止任何人往这个空位里插入新书。但是他不锁任何现有的书
- 临键锁:这其实就是行锁+间隙锁的组合技。他不但要锁住你想要的那本书,还要锁住他旁边的空位。这是在InnoDB在默认隔离级别(可重复读)下防止幻读的手段。
具体实现
- 表锁:就是锁住整张表,实现简单,开销小。
LOCK TABLES table_name READ; -- 加读锁(共享锁),别人可读不可写 |
- 行锁:锁住表中单行或多行记录,并发度高。
行锁是隐式的,在事务中自动加锁
BEGIN; |
- 在UPDATE,DELETE,SELECT….FOR UPDATE等语句执行时,都会自动加上行锁
- 间隙锁 && 临键锁 :锁住一个索引区间(开区间,不包含记录本身)
主要是为了防止幻读。同样也是隐式的,在可重复读隔离级别下自动启动
当你执行 SELECT * FROM user WHERE age BETWEEN 10 ADN 20 FOR UPDATE; 时,InnoDB不仅会锁住age在10-20之间所有已存在的记录(行锁)
还会锁住age在10-20之间的空闲空间(间隙锁),阻止任何新纪录插入到这个区间(如age=15的新用户)
注意事项
行锁不是直接锁磁盘上的记录!
行锁是锁在索引上的,如果WHERE条件字段没有索引,InnoDB就无法精确定位到哪一行,只能锁整个表(升级为表锁)。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 花海!
