![1fa868808612378564e44cc4dcb7119d.png](https://i-blog.csdnimg.cn/blog_migrate/8856de8e838e9e6e11482387efd7bd98.jpeg)
关注:架构师学习路线,每日更新互联网最新技术文章与你不断前行,实战资料,笔试面试
一、前言
MySQL 的并发控制是在数据安全性和并发处理能力之间的权衡,通过不同的锁策略来决定对系统开销和性能的影响。
只要存在多个客户端同时修改更新数据,就会存在并发问题,MySQL 通过 MVCC 和锁来处理这一问题。
二、锁的粒度 Lock Type
MySQL 源码中定义了两种锁的粒度,分别是表锁和行锁。
/** Lock types */
#define LOCK_TABLE 16 /*!< table lock */
#define LOCK_REC 32 /*!< record lock */
1、表锁
表锁由 MySQL Server 控制,优点是开销小、加锁快,不会产生死锁,缺点是加锁粒度大,发生锁冲突的概率大,并发度比较低。
一般 DDL 语句会自动加表锁,也可以手动指定。表锁分为读锁和写锁。
//加读锁
lock table products read;
//加写锁
lock table products write;
当对表加了读锁,则会话只能读取当前被加锁的表,其它会话仍然可以对表进行读取但不能写入。当对表加了写锁,则会话可以读取或写入被加锁的表,其它会话不能对加锁的表进行读取或写入。
2、行锁
行锁由存储引擎实现,InnoDB 支持,而 MyISAM 不支持。行锁的优点是锁粒度小,发生锁冲突概率小,并发度高,缺点是开销大、加锁慢,并且可能产生死锁。
InnoDB 行锁是通过索引项加锁来实现的,只有通过索引条件检索数据,才能锁住指定的索引记录,否则将使用行锁锁住全部数据(有文章称会退化为表锁,是错误的理解)。
表级锁适合查询多、更新少的场景,行级锁适合按索引更新频率高的场景。InnoDB 默认使用行级锁。
三、锁的模式 Lock Mode
MySQL 源码中定义了多种锁的模式,如下:
/* Basic lock modes */
enum lock_mode {
LOCK_IS = 0, /* intention shared */
LOCK_IX, /* intention exclusive */
LOCK_S, /* shared */
LOCK_X, /* exclusive */
LOCK_AUTO_INC, /* locks the auto-inc counter of a table in an exclusive mode */
...
};
1、共享锁和排它锁
共享锁和排它锁都是行级锁。
Shared Lock (S 锁),共享锁,也称为读锁。当事务对行加共享锁后,允许其它事务对相同行加共享锁,但不允许加排它锁。
Exclusive Lock (X 锁),排它锁,也称为写锁。当事务对行加排它锁后,不允许其它事务对相同行加共享锁或排它锁。
2、意向锁
意向锁分为意向共享锁和意向排它锁,意向锁是表锁。
Intention Shared Lock (IS),意向共享锁,也称为意向读锁。意向共享锁表示有事务打算在行记录上加共享锁,在事务获取行 S 锁前,必须先获得 IS 锁或更高级别的锁。
Intention Exclusive Lock (IX),意向排它锁,也称为意向写锁。意向排它锁表示有事务打算在行记录上加排它锁,在事务获取行 X 锁前,必须先获 IX 锁。
意向锁之间不会发生冲突,但共享锁、排它锁、意向锁之间会发生冲突,如下表所示。
| X | IX | S | IS
X | Conflict | Conflict | Conflict | Conflict
IX | Conflict | Compatible | Conflict | Compatible
S | Conflict | Conflict | Compatible | Compatible
IS | Conflict | Compatible | Compatible | Compatible
3、自增锁
AUTO-INC Locks,自增锁,它是一种特殊的表锁。当表有设置自增 auto_increment 列,在插入数据时会先获取自增锁,其它事务将会被阻塞插入操作,自增列 +1 后释放锁,如果事务回滚,自增值也不会回退,所以自增列并不一定是连续自增的。
四、行锁的分类
MySQL 中定义了四种行锁的分类:
#define LOCK_ORDINARY 0
#define LOCK_GAP 512
#define LOCK_REC_NOT_GAP 1024
#define LOCK_INSERT_INTENTION 2048
1、记录锁
Record Locks,记录锁是索引记录的锁定。例如 SELECT a FROM t WHERE