一,介绍
引入概念:
线程A在开启事务后,执行更新操作时,会对对应的行添加一个行锁;此时线程B再加表锁时,并不能直接添加,需要从第一条记录开始一直到最后一条检查表中是否有行锁,以及存在的行锁的类型来确定线程B到底能不能加表锁,影响性能。
为了解决这个问题,避免DML在执行时,加的行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查。
二,分类
1,意向共享锁:(IS):与表锁共享锁(read)兼容,与表锁排他锁(write)互斥
2,意向排他锁:(IX):与表锁共享锁(read)及表锁排他锁(write)都互斥,意向锁之间不会互斥。
可以通过以下SQL查看意向锁的加锁情况:
select OBJECT_SCHEMA,OBJECT_NAME,INDEX_NAME,LOCK_TYPE,LOCK_MODE,LOCK_DATA from performance_schema.data_locks;
三,演示
1,意向共享锁与表锁的兼容性
在窗口console3中开启事务,执行查询操作并添加行锁共享锁,同时为该表加上意向共享锁,未提交事务;
在窗口console4中开启事务,为表加上读锁,加锁成功,因为意向共享锁与表锁的读锁兼容;
在窗口console4中为表加上写锁,阻塞,因为意向共享锁与表锁的读锁互斥;
在窗口console3中事务提交,console3的行锁以及涉及到的共享锁都会释放,console4的表锁的写锁并添加成功。
2,意向排他锁与表锁的兼容性
在窗口console3中开启事务,执行更新操作并添加行锁共享锁,同时为该表加上意向排他锁,未提交事务;
在窗口console4中开启事务,为表加上表锁读锁,此时InnoDB引擎回去判断这张表的意向锁的情况,发现是意向排他锁,产生互斥状态,造成阻塞;
在窗口console3中提交事务,console4中的表锁读锁才添加成功。
【表锁写锁同理】