乐观锁 / 悲观锁
乐观锁、悲观锁是关于锁的两种思想观念,并不是指具体的锁机制。
乐观锁
乐观锁的思想对数据的处理持乐观态度,乐观的认为数据一般情况下不会发生冲突,只有提交数据更新时,才会对数据是否冲突进行检测。 乐观锁的思想可以通过数据唯一自增版本号或者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)。持有行锁也意味着持有了表的意向锁。意向锁是一种状态标识,表明该表的某些行被锁定了,因此不能对整表进行全表更新(存在行记录被锁定)或查询(存在行记录被排他锁锁定)。因此要进行全表更新或事务查询,需要先获得意向锁。