锁机制基本原理
锁机制的基本原理可以概括为:事务在修改数据之前,需要先获得相应的锁;
获得锁之后,事务便可以修改数据;
该事务操作期间,这部分数据是锁定的,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁
锁的分类
行锁与表锁
按照粒度,锁可以分为表锁、行锁以及其他位于二者之间的锁。
表锁在操作数据时会锁定整张表,并发性能较差;行锁则只锁定需要操作的数据,并发性能好。
但是由于加锁本身需要消耗资源(获得锁、检查锁、释放锁等都需要消耗资源),因此在锁定数据较多情况下使用表锁可以节省大量资源。MySQL中不同的存储引擎支持的锁是不一样的,例如MyIsam只支持表锁,而InnoDB同时支持表锁和行锁,且出于性能考虑,绝大多数情况下使用的都是行锁。
行锁实现有三种算法,又称为:临键锁next-key、间隙所gap和记录锁record。默认隔离级别不可重复读使用临键锁作为行锁的实现算法。
InnoDB的行锁是通过给索引上的索引项加锁来实现的,只有通过索引条件进行数据检索,InnoDB才使用行级锁,否则InnoDB 将使用表锁(锁住全部索引)。
锁的类型
innodb一共有5种锁:共享锁(行)、排它锁(行)、意向共享锁(表)、意向排它锁(表)、自增锁。
1.共享锁:也称为读锁,可以让多个事务同时对数据进行操作时可以访问到数据,但不能修改。使用方式:
select语句+LOCK IN SHARE MOD
2.排它锁:又称为写锁。一个事务持有了一行数据的排它锁时,其他事务不能再访问和修改这行数据。innodb默认update delete insert上会加排它锁,select使用方式:
select语句+for update
3.意向共享锁:在事务对某一行加共享锁时,要先给该表加上意向共享锁。
4.意向排它锁:在事务对某一行数据加排它锁时,必须要先给该表加上意向排它锁。
作用是,当某一个事务需要去锁表时,不用判断每一行上是否有不兼容的锁,只需要判断有没有意向锁。如写操作锁表,判断某行数据是否存在共享锁,如果拿不到意向锁就可直接阻塞操作。
5.自增锁:针对自增列自增长的一个特殊的表级别锁。
锁的算法
1.临键锁next-key:当sql语句按照范围查询,并且有数据命中的时候会给索引加上临键锁,锁住命中索引项的前一个索引到命中索引项的后一个索引之间的一个左开右闭区间。因为锁住区间,所以避免了幻读。
2.间隙锁gap:当sql语句查找未命中时,会锁住查询条件值附近的间隙。
3.记录锁record:使用唯一索引查询并精准匹配到数据,则只会锁住该索引项。
这三种算法锁的原理基于b+tree索引。
如何查看锁信息
有多种方法可以查看InnoDB中锁的情况,例如:
1 2 |
|
eg:下面来看一个例子
1 2 3 4 5 6 |
|
此时查看锁的情况:
show engine innodb status查看锁相关的部分:
通过上述命令可以查看事务24052和24053占用锁的情况;其中lock_type为RECORD,代表锁为行锁(记录锁);lock_mode为X,代表排它锁(写锁)。
除了排它锁(写锁)之外,MySQL中还有共享锁(读锁)的概念
参考文章:https://www.cnblogs.com/kismetv/p/10331633.html