文章目录
一、按模式分类
乐观锁
并不会真正的去锁某行记录,而是通过一个版本号来实现的。
悲观锁
悲观锁总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的数据库所用的锁如行锁、表锁等都是悲观锁。
二、按粒度分类
全局锁
对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的MDL(元数据锁)、DDL(数据定义语言)语句、更新操作的事务提交语句都将被阻塞。做全库的逻辑备份、全库的导出,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。
表级锁
会对当前操作的整张表加锁。表级锁的开销较小,加锁快,但由于其锁定粒度大,可能会导致并发度下降,特别是在写操作较多或者并发度较高的场景下。MySQL中的MyISAM与InnoDB都支持表级锁定。
页级锁
开销和加锁速度介于表锁和行锁之间,并发度一般。页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但并发性能低,行级锁速度慢,但并发性能高。页级锁的目的是为了取得两者之间的平衡,所以出现了页级锁。
行级锁
粒度最低的锁,发生锁冲突的概率也最低,并发度最高。但加锁慢、开销大,容易发生死锁现象。MySQL中只有InnoDB支持行级锁。行级锁并不是直接锁记录,而是锁索引。
三、按属性分类
共享锁(S锁)
共享锁(S锁)又称读锁。若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读取A,但在T释放S锁之前不能对A做任何修改。
排他锁(X锁)
排他锁(X锁)又称写锁。若事务T对数据对象A加上X锁,则事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的X锁。这保证了其他事务在T释放X锁之前不能再读取和修改A。
四、按状态分类
意向共享锁(IS锁)
表示某个事务打算在表上加共享锁。IS锁是表级锁,它表明有事务打算读取表中的某些数据,但还没有实际读取。
意向排他锁(IX锁)
表示某个事务打算在表上加排他锁。IX锁也是表级锁,它表明有事务打算修改表中的某些数据。
五、按算法分类
记录锁(Record Lock)
索引记录锁,仅锁住索引记录。如果一条SQL语句操作了主键索引,MySQL就会锁定这条主键索引。
间隙锁(Gap Lock)
锁定索引记录之间的间隙。间隙锁可以防止其他事务在已经锁定的范围内插入新的行,这有助于解决幻读问题。但间隙锁可能会影响到数据库的并发性能,尤其在需要大量插入操作的高并发场景下。
临键锁(Next-Key Lock)
是记录锁和间隙锁的组合,它锁住了索引记录及其前面的间隙。InnoDB的默认事务隔离级别是REPEATABLE READ,在这种级别下,如果使用SELECT…IN SHARE MODE或者SELECT…FOR UPDATE语句,那么InnoDB会在必要情况下使用临键锁,以防止幻读。
六、其他锁
插入意向锁(Insert Intention Lock)
当多个事务同时进行插入操作时,为了避免它们在相同范围内插入相同的数据,数据库系统会使用插入意向锁来进行优化。插入意向锁是一种特殊的间隙锁,它表示有事务打算在某个间隙中插入新数据,但不会阻止其他事务也在该间隙中插入数据。
自增锁(Auto-inc Lock)
自增锁是一种特殊的表级锁,用于保证自增列的唯一性和连续性。当一个事务向表中插入新行时,MySQL会使用自增锁来确保自增列的值是唯一的,并且是按照递增的顺序生成的。
隐式锁
是MySQL数据库在执行某些操作时自动为数据添加的锁,用于保证多个并发操作之间的正确性和一致性。