slug
status
password
icon
AI summary
date
summary
tags
type
category
1、mysql锁1.1、锁粒度表级锁行级锁页级锁总结1.2、共享锁、排它锁1.3、加锁模式记录锁(Record Locks)间隙锁(Gap Locks)临键锁(Next-Key Locks)意向锁插入意向锁
1、mysql锁
1.1、锁粒度
表级锁、行级锁、页级锁
表级锁
行级锁
页级锁
总结
1.2、共享锁、排它锁
InnoDB 实现了标准的行级锁,包括两种:共享锁(简称 s 锁)、排它锁(简称 x 锁)。
对于共享锁而言,对当前行加共享锁,不会阻塞其他事务对同一行的读请求,但会阻塞对同一行的写请求。只有当读锁释放后,才会执行其它事物的写操作。
对于排它锁而言,会阻塞其他事务对同一行的读和写操作,只有当写锁释放后,才会执行其它事务的读写操作。

简而言之,就是
读锁会阻塞写(X),但是不会堵塞读(S)。而写锁则会把读(S)和写(X)都堵塞
对于InnoDB 在RR(MySQL默认隔离级别) 而言,对于 update、delete 和 insert 语句, 会自动给涉及数据集加排它锁(X);
对于普通 select 语句,innodb 不会加任何锁。如果想在select操作的时候加上 S锁 或者 X锁,需要我们手动加锁。
用 select… in share mode 获得共享锁,主要用在需要数据依存关系时来确认某行记录是否存在,并确保没有人对这个记录进行 update 或者 delete 操作。
但是如果当前事务也需要对该记录进行更新操作,则有可能造成死锁,对于锁定行记录后需要进行更新操作的应用,应该使用 select… for update 方式获得排他锁。
1.3、加锁模式
记录锁(Record Locks)
- 同时查询语句必须为精准匹配(=),不能为 >、<、like等,否则也会退化成临键锁。
其他实现
在通过 主键索引 与 唯一索引 对数据行进行 UPDATE 操作时,也会对该行数据加记录锁:
==记录锁是锁住记录,锁住索引记录,而不是真正的数据记录.==
==如果要锁的列没有索引,进行全表记录加锁==
记录锁也是排它(X)锁,所以会阻塞其他事务对其插入、更新、删除。

间隙锁(Gap Locks)
临键锁(Next-Key Locks)

- 记录锁存在于包括主键索引在内的唯一索引中,锁定单条索引记录。
- 间隙锁存在于非唯一索引中,锁定开区间范围内的一段间隔,它是基于临键锁实现的。
- 临键锁存在于非唯一索引中,该类型的每条记录的索引上都存在这种锁,它是一种特殊的间隙锁,锁定一段左开右闭的索引区间。
意向锁
- 意向锁是一种 不与行级锁冲突的表级锁,这一点非常重要。
- 意向锁是 InnoDB 自动加的, 是由数据引擎自己维护的,用户无法手动操作意向锁,
==在为数据行加共享 / 排他锁之前,InooDB 会先获取该数据行所在在数据表的对应意向锁。==
- 意向锁是在 InnoDB 下存在的内部锁,对于MyISAM 而言 没有意向锁之说。
插入意向锁
- 插入意向锁之间互不排斥,所以即使多个事务在同一区间插入多条记录,只要记录本身(主键、唯一索引)不冲突,那么事务之间就不会出现冲突等待。
虽然插入意向锁中含有意向锁三个字,但是它并不属于意向锁而属于间隙锁,因为意向锁是表锁而插入意向锁是行锁。
现在我们可以回答开头的问题了:
1、 使用插入意向锁与记录锁。
2、事务 A 不会阻塞事务 B。
- age 区间在(15,20] 的间隙锁。
最终,事务 A 插入了该行数据,并锁住了(10,20] 这个区间。
随后事务 B 试图插入一行数据:
因为 16 位于(15,20] 区间内,而该区间内又存在一把间隙锁,所以事务 B 别说想申请自己的间隙锁了,它甚至不能获取该行的记录锁,
自然只能乖乖的等待 事务 A结束,才能执行插入操作。
很明显,这样做事务之间将会频发陷入阻塞等待,插入的并发性非常之差。
这时如果我们再去回想我们刚刚讲过的插入意向锁,就不难发现它是如何优雅的解决了并发插入的问题。
- 插入意向锁是一种特殊的间隙锁。
- 插入意向锁在锁定区间相同但记录行本身不冲突的情况下互不排斥。