锁
- 共享锁(S锁)
假设事务T1对数据A加上共享锁,那么事务T2可以读数据A,不能修改数据A。 - 排他锁(X锁)
假设事务T1对数据A加上共享锁,那么事务T2不能读数据A,不能修改数据A。
我们通过update、delete等语句加上的锁都是行级别的锁。只有LOCK TABLE … READ和LOCK TABLE … WRITE才能申请表级别的锁。意向锁是加在表上的,
- 意向共享锁(IS锁)
一个事务在获取(任何一行/或者全表)S锁之前,一定会先在所在的表上加IS锁。 - 意向排他锁(IX锁)
一个事务在获取(任何一行/或者全表)X锁之前,一定会先在所在的表上加IX锁。
IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突。
为什么需要意向锁
先给出结论:意向锁主要是加表锁时提升互斥判断的效率,加速检测表锁与行锁的冲突,实现多粒度锁的表锁快速判断。
场景:如果某个事务要对表加X锁, 对表加锁时,不但要感知当前表的加锁情况, 还要感知表中所有行的加锁情况, 才能判定是否能加锁成功, 但是对行加锁情况感知需要遍历每一行才行, 效率低。于是给表上加一个意向锁,但需要锁整个表时可以直接根据意向锁判断,简单快捷。
所以我们可以看到上图中,意向锁与意向锁之间都是兼容的。但与行锁互有影响, 于是有人说,意向锁是为了表级锁加锁时防止和行级锁产生冲突的一个解决方案。
什么时候加意向锁
意向锁是表级别的锁,是InnoDB存储引擎自己维护的,用户无法手动添加意向锁。当我们要对某个page中的一行记录进行锁定时,需要对上层的table加意向锁——IS/IX。
加锁语句
select 语句 需要加锁的只有2种场景:
- 加排他锁可以使用select …for update语句
- 加共享锁可以使用select … lock in share mode语句