作者:小强Zzz
来源:SegmentFault思否社区
前言mysql按锁的范围分三种
表级锁:开销小,加锁快;不会出现死锁,锁定粒度大,发生锁冲突概率最高,并发度最低。
行级锁:开销大,加锁慢,会出现死锁,锁定粒度小,发生锁冲突的概率最低,并发度最高。
页面锁:开销和加锁时间界于表锁和行锁之间,会出现死锁,锁定粒度界于表锁和行锁之间,并发度一般。
从上述三种锁的特点来看,很难说哪种锁更好,只能就具体应用的特点来说哪种锁更合适。比如,MyISAM和MEMORY引擎采用的是表级锁;InnoDB引擎既支持行级锁,也支持表级锁,但默认情况下采用行级锁。InnoDB的加锁模式InnoDB实现了以下两种类型的行锁。共享锁(S):允许一个事务读一行,阻止其他事务获得相同数据的排他锁,也叫读锁。
排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享锁与排他锁,也叫写锁。
同时mysql还支持与行共享锁和行排他锁类似的表共享锁和表排他锁因为锁的粒度不同,表锁的范围覆盖了行锁的范围,所以表锁和行锁会产生冲突,例如事务A对表中某一行数据加了行锁,然后事务B想加表锁,正常来说是应该要冲突的。要判断是否冲突就得遍历每一行数据了,这样的效率不高,因此我们就有了意向表锁。
意向锁的主要目的是为了使得行锁和表锁共存,事务在申请行锁前,必须先申请表的意向锁,成功后再申请行锁。
意向锁分为意向共享锁和意向排他锁。
意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁之前必须先去的该表的意向共享锁
意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的意向排他锁。
上述锁模式的兼容情况如下表所示如果一个事务请求的锁模式与当前的锁模式兼容,InnoDB就将请求的锁授予该事务,反之,如果两者不兼容,该事务就要等待锁释放。
意向锁是表级锁,但是却表示事务正在读或写某一行记录,而不是整个表,所以意向锁之间不会产生冲突,真正的冲突在加行锁时检查。
加锁方法意向锁是InnoDB自动加的,不需要用户干预。隐式上锁对于UPDATE,DELETE和INSERT语句,InnoDB会自动给设计数据集加排他锁;对于普通SELETE语句,INNODB不会加任何锁;InnoDB会根据隔离级别在需要的时候自动加锁;显式上锁select*fromtableNamelockinsharemode;//读锁select*fromtableNameforupdate;//写锁解锁
提交事务(