InnoDB 支持多粒度锁,它允许行级锁与表级锁共存,而意向锁就是其中的一种表锁
1、意向锁的存在是为了协调行锁和表锁的关系,支持多粒度的锁并存
2、意向锁是一种不与行锁冲突表级锁,这一点非常重要
3、表明某个事务正在某些行持有锁或该事务准备去持有锁
意向锁通常有两种类型:
-
意向锁共享锁(IS):表示事务打算在表中的各个行上设置共享锁(S锁)
-
意向锁排他锁(IX):表示事务打算对表中的各个行设置排他锁(X锁)
意向锁是InnoDB自动加上的,加锁时遵从下面两个协议:
-
事务在获取表中行的共享锁之前,必须先获取表上的IS锁或更强的锁
-
事务在获取表中行的排他锁之前,必须先获取表上的IX锁
即:意向锁是由存储引擎自己维护的,用户无法手动操作意向锁,在为数据行加共享 / 排他锁之前,InnoDB会先获取该数据行所做数据表的对应意向锁
1、意向锁要解决的问题
现在有两个事务,分别是T1 和 T2,其中 T2试图在该表级别上加共享或排它锁,如果没有意向锁存在,那么T2就需要去检查各个页或行是否存在锁,如果存在意向锁,那么此时T2就会受到由T1控制的表级别意向锁而导致阻塞。T2在锁定该表前不必检查各个页或行锁,而只需检查表上的意向锁。简单说就是给更大一级别的空间示意里面是否已经上过锁。
在数据表的场景中,如果我们某一行数据加上了排它锁,数据库会自动给更大一级的空间,比如数据页或数据表加上意向锁,告诉其他人这个数据页或数据表已经有人上过排它锁了,这条当其他人想要获取数据表排它锁的时候,只需要了解是否有人已经获取这个数据表的意向锁排它所即可。
-
如果事务想要获得数据表中某些记录的共享锁,就需要在数据表上添加意向共享锁
-
如果事务想要获得数据表中某些记录的排它锁,就需要在数据表上添加意向排它锁
为了更好的说明意向共享锁,可以参照下面的顺序执行流和实例图: