MySQL 锁

  MySQL 的锁机制,主要用于高并发场景下,比较重要的知识点是保证数据的一致性的和事务隔离性,在高并发下控制并发访问。

MySQL锁相关知识点

 

 

 

锁的种类

  MySQL 中锁的分类按照不同类型的划分可以分成不同的锁,

  • 按照锁的粒度:
    • 表锁:粒度最大的锁,开销小,加锁快,不会出现死锁,但是由于粒度太大,因此造成锁的冲突几率大,并发性能低。常见的有 MyISAM 储存引擎就支持表锁,MyISAM的表锁模式有两种:表共享读锁和表独占写锁

      当一个线程获取到 MyISAM 表的读锁的时候,会阻塞其他用户对该表的写操作,但是不会阻塞其它用户对该用户的读操作。

      相反的,当一个线程获取到 MyISAM 表的写锁的时候,就会阻塞其它用户的读写操作对其它的线程具有排它性。

    • 页锁:粒度是介于行锁和表锁之间的一种锁,页锁是在 BDB 中支持的一种锁机制,很少提及和使用
    • 行锁:粒度最小的锁机制,行锁的加锁开销性能大,加锁慢,并且会出现死锁,但是行锁的锁冲突的几率低,并发性能高。

      行锁是 InnoDB 默认的支持的锁机制,MyISAM 不支持行锁,这个也是 InnoDB 和 MyISAM 的区别之一。

      行锁在使用的方式上可以划分为:共享读锁( S 锁)排它写锁( X 锁)

      当一个事务对 MySQL 中的一条数据行加上了 S 锁,当前事务不能修改该行数据只能执行读操作,其他事务只能对该行数据加 S 锁不能加 X 锁。若是一个事务对一行数据加了 X 锁,该事务能够对该行数据执行读和写操作,其它事务不能对该行数据加任何的锁,既不能读也不能写。

  • 按照使用的方式共享锁排它锁
  • 按照思想:数据库管理系统中为了控制并发,保证在多个事务执行时的数据一致性以及事务的隔离性,使用悲观锁和乐观锁来解决并发场景下的问题。
    • 乐观锁:需要程序员自己去实现的锁机制
    • 悲观锁:悲观锁的实现是基于Mysql自身的锁机制实现

悲观锁和乐观锁是在很多框架都存在的一种思想,不要狭义地认为它们是某一种框架的锁机制。

 

MyISAM

  MyISAM中 默认支持的表级锁有两种:共享读锁独占写锁。表级锁在 MyISAM 和 InnoDB 的存储引擎中都支持,但是 InnoDB 默认支持的是行锁。

  MySQL 中平时读写操作都是隐式的进行加锁和解锁操作,MySQL 已经自动实现加锁和解锁的操作,若是想要测试锁机制,就要显示的自己控制锁机制。

MySQL 中可以通过以下 sql 来显示的在事务中显式的进行加锁和解锁操作:

-- 显式的添加表级读锁
LOCK TABLE 表名 READ
-- 显示的添加表级写锁
LOCK TABLE 表名 WRITE
-- 显式的解锁(当一个事务commit的时候也会自动解锁)
unlock tables;

 

MyISAM 表级写锁

CREATE TABLE IF NOT EXISTS employee (
    id INT PRIMARY KEY auto_increment,
    name VARCHAR(40),
    money INT
)ENGINE MyISAM

INSERT INTO employee(name, money) VALUES('黎杜', 1000);
INSERT INTO employee(name, money) VALUES('非科班的科班', 2000);
示例使用的表结构及数据

相关文章: