一、记录锁(Record Locks)
记录锁(Record Locks) : 记录锁就是为某行记录加锁(也就是行锁), 其特点为:
- 列必须为唯一索引列或主键列,否则加的锁就会变成临键锁
- 查询语句必须为精准匹配 = ,不能为 >、<、like等,否则也会退化成临键锁。
-- 在id=1的数据上添加记录锁,阻止其他事务对其进行更新操作
select * from test where id = 1 FOR UPDATE
-- 通过主键索引和唯一索引对数据进行update操作时,也会对该行数据加记录锁
update set age = 50 where id = 1; -- id是主键
记录锁也是排它(X)锁,所以会阻塞其他事务对其插入、更新、删除。之前介绍过排它锁,这里就不在详细讲解。
二、间隙锁(Gap Lock)
间隙锁(Gap Lock) : 间隙锁是封锁索引记录中的间隔,可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间。
SELECT * FROM table WHERE id BETWEN 1 AND 10 FOR UPDATE;
即所有在 (1,10) 区间内的记录行都会被锁住,所有id 为 2、3、4、5、6、7、8、9 的数据行的插入会被阻塞,但是 1 和 10 两条记录行并不会被锁住。后面我们会通过案例详细演示间隙锁。
三、临键锁 ( Next-Key Locks )
临键锁 ( Next-Key Locks ) : next-key锁其实包含了记录锁和间隙锁,即锁定一个范围,并且锁定记录本身,InnoDB默认加锁方式是next-key 锁。
通过临建锁可以解决幻读的问题。 每个数据行上的非唯一索引列上都会存在一把临键锁,当某个事务持有该数据行的临键锁时,会锁住一段左开右闭区间的数据。