存储引擎:InnoDB
一、意向锁
意向锁的分类:
- 意向共享锁,事务想要给数据库某些行加共享锁,需要先加上意向共享锁
- 意向互斥锁,事务想要给数据库某些行加互斥锁,需要先加上意向互斥锁
意向锁是表锁 !!!
意向锁不会与行级的共享 / 排他锁互斥
为什么需要意向锁?
主要为了实现多粒度锁。
- LOCK TABLE table_name READ;用共享锁锁住整个表
- LOCK TABLE table_name WRITE;用互斥锁锁住整个表
假设没有意向锁,事务A使用行锁锁住其中一行,事务B申请表的互斥锁,然后修改整个表,行锁和表锁就会发生冲突,要解决冲突,事务B需要等待事务A锁住的行锁释放,但是事务B并不知道事务A锁住的是哪一行,所以事务B会遍历数据库每一行判断是否有行锁,这是一个非常耗时的过程。
为了解决上述问题引入意向锁,事务A在加行锁前,先需要给表加上对应的意向锁,这样如果事务B来获取表锁,需要先判断表上是否有意向锁,如果有意向锁,则阻塞,等待事务A的锁释放
意向锁之间不互斥,包括意向互斥锁,也就是两个意向互斥锁可以共存
意向锁和表锁之间兼容关系:
意向共享锁(IS) | 意向互斥锁(IX) | |
共享锁(IS) | 兼容 | 互斥 |
互斥锁(IX) | 互斥 | 互斥 |
二、元数据锁
元数据锁属于表锁范畴,元数据即数据字典信息
- MDL 不需要显式使用,在访问一个表的时候会被自动加上
- MDL的作用是维护数据的一致性
为什么需要元数据锁
线程A查询数据库,线程B对表结构进行变更,比如说删除某一列,修改列名,那么查询结果和数据库表结构对应不上,这就冲突了
- MDL锁不需要显示使用,在访问表结构的时候被自动加上
- 对表做增删改查操作,加MDL读锁,对表结构变更的时候加MDL写锁
- 兼容性和正常行锁读写锁保持相同,读读兼容,读写,写写不兼容
MDL锁可能带来的问题:
- 事务A查询表记录,事务B给表加字段,事务C查询表记录
- 事务A会给表加MDL读锁,事务B会加MDL写锁,事务C给表加读锁
读写锁不兼容,事务B必须等待事务A提交结束才能继续执行,事务C虽然是读锁,读锁之间相互兼容,但是由于事务B的存在,也会阻塞,如果这时查询请求很频繁,会造成大量请求失败。