MYSQL/InnoDB的锁

82 阅读3分钟

乐观锁 / 悲观锁

乐观锁、悲观锁是关于锁的两种思想观念,并不是指具体的锁机制。

乐观锁

乐观锁的思想对数据的处理持乐观态度,乐观的认为数据一般情况下不会发生冲突,只有提交数据更新时,才会对数据是否冲突进行检测。 乐观锁的思想可以通过数据唯一自增版本号或者CAS等机制实现。

悲观锁

乐观锁的思想对于数据的处理持悲观态度,总认为会发生并发冲突,获取和修改数据时,别人会修改数据。所以在整个数据处理过程中,都需要将数据锁定。 悲观锁的实现通常要依赖具体的锁机制

共享锁 / 排他锁

共享锁(读锁、S锁)

共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改

排他锁(写锁、X锁)

排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁(不管是读锁还是写锁都不能加),只有持有锁的那个事务才可以读取和修改该数据,其他拿不到锁的事务只能等待持有锁的事务释放锁。

隐式锁定

MySQL InnoDB引擎默认的修改数据语句,update/delete/insert 都会自动给涉及到的数据加上排他锁,select 语句默认不会加任何锁类型

显示锁定

select ... for update(排他锁)

select ... lock in share mode(共享锁)

行锁和表锁

行锁

行锁是指上锁的时候锁住的是表的某一行或多行记录,其他事务访问同一张表时,只有被锁住的记录不能访问,其他的记录可正常访问。 行锁的本质是在索引节点上加锁,如果无法在索引节点上加锁,那就会直接变成整张表的锁

记录锁(Record Lock)

记录锁也属于行锁中的一种,只不过事务在加锁后锁住的只是表的某一条记录。

触发条件: 精准条件命中,并且命中的条件字段是唯一索引;

间隙锁 (Gap Lock)

间隙锁属于行锁中的一种,范围查找时,会把整个范围的数据全部锁定住,即便这个范围内不存在的一些数据(间隙),也会锁定住。

触发条件: 范围查询当前读,未全命中记录。

临键锁(NextKey Lock)

临键锁也属于行锁的一种,并且它是INNODB的行锁默认算法,总结来说它就是记录锁和间隙锁的组合,临键锁会把查询出来的记录锁住,同时也会把该范围查询内的所有间隙空间也会锁住,再之它会把上下相邻的区间也锁住。

触发条件: 范围查询查询条件命中非唯一索引、REPEATABLE_READ(可重复读)的事务级别。

意向锁

意向锁是一种表锁,也分为意向共享锁(IS)和意向排他锁(IX)。持有行锁也意味着持有了表的意向锁。意向锁是一种状态标识,表明该表的某些行被锁定了,因此不能对整表进行全表更新(存在行记录被锁定)或查询(存在行记录被排他锁锁定)。因此要进行全表更新或事务查询,需要先获得意向锁。