在 MySQL 中,锁是用于并发控制的重要机制。当多个事务同时执行操作访问同一数据时,锁的作用就体现出来了。根据锁的粒度,MySQL 中的锁可以分为表级锁和行级锁。其中,表级锁是对整张表加锁,而行级锁则是只针对某一行或某几行加锁。下面将详细介绍 MySQL 中的锁种类:
一、表级锁
共享锁也称为读锁,它是一种共享锁定,允许多个事务同时读取同一个数据行,但不允许其他事务进行修改或删除该行数据。多个事务可以同时持有共享锁定,但不能与排他锁定同时存在。
在 MySQL 中使用 SELECT ... LOCK IN SHARE MODE
或 SELECT ... FOR UPDATE
语句可以获取共享锁:
SELECT ... LOCK IN SHARE MODE
:会在读取过程中添加共享锁,不会阻塞其他事务对同一行的读取操作。SELECT ... FOR UPDATE
:会在读取过程中添加排他锁,阻塞其他事务读取和修改同一行数据。排他锁也称为写锁,它是一种排他锁定,不允许其他事务进行读取、修改或删除该行数据。只有持有排他锁的事务才能对该行进行修改或删除操作。
在 MySQL 中使用 SELECT ... FOR UPDATE
语句可以获取排他锁。
二、行级锁
记录锁是针对某一行数据进行加锁,保护该行数据不受其他事务的读取、修改或删除。当一个事务正在对某个数据行进行操作时,它会自动地对该数据行进行锁定,锁定的范围即为记录锁。MySQL 中的记录锁又可分为:
MySQL 中通过 SELECT ... FROM ... WHERE ... FOR UPDATE
或 SELECT ... FROM ... WHERE ... LOCK IN SHARE MODE
来实现记录锁的加锁操作。
间隙锁用于保护索引键值之间的“空隙”,以防止其他事务在这些键值之间插入数据。MySQL 中的间隙锁又分为:
MySQL 中通过 SELECT ... FROM ... WHERE ... LOCK IN SHARE MODE
或 SELECT ... FROM ... WHERE ... FOR UPDATE
语句来加锁。
三、其他锁
在 MySQL 5.5 及以后版本中,InnoDB 存储引擎针对行级锁进行了优化,加入了新的锁机制——Next-Key Locks(下一键锁)。Next-Key Locks 是记录锁和间隙锁的组合,利用它们的特性解决了幽灵读(Phantom Reads)问题。
全局锁指的是锁住整个数据库实例,只有一个事务可对整个数据库实例进行写操作。在 MySQL 中使用 FLUSH TABLES WITH READ LOCK
和 SET GLOBAL read_only = ON
命令可以实现全局锁的操作,一般用于备份和数据迁移等操作。
总结:
在 MySQL 中,锁是实现并发控制的重要机制,根据锁的粒度可以分为表级锁和行级锁。表级锁包括共享锁和排他锁,行级锁包括记录锁和间隙锁,同时也有行级锁优化和全局锁等其他锁。锁的作用是为了保证并发读写操作的正确性,但过度使用锁会影响系统的性能和并发度,因此在使用锁时需谨慎。