MYSQL中锁的分类与加锁方式小结

 更新时间:2026年03月17日 10:32:48   作者:Binary-Jeff  
MySQL通过表级锁和行级锁两种机制来控制并发事务对数据的访问,以避免数据不一致、脏读和幻读等问题,表级锁包括显式锁、元数据锁和意向锁,而行级锁包括记录锁、间隙锁和临键锁,本文介绍MYSQL中锁的分类与加锁方式小结,感兴趣的朋友跟随小编一起看看吧

在数据库并发环境中,多个事务可能同时访问同一份数据。如果没有合理的并发控制机制,就会出现数据不一致、脏读、幻读等问题。

为了解决这些问题,MySQL 在存储引擎层提供了一套完整的 锁机制(Lock Mechanism),用于控制多个事务对数据的访问顺序。

从整体结构上看,MySQL 的锁可以按照 锁的粒度 分为两大类:

MySQL 锁
│
├── 表级锁
│   ├── 表锁(LOCK TABLES)
│   ├── 元数据锁(MDL Lock)
│   └── 意向锁(Intention Lock)
│
└── 行级锁(InnoDB)
    ├── 记录锁(Record Lock)
    ├── 间隙锁(Gap Lock)
    └── 临键锁(Next-Key Lock)

下面分别进行介绍。

一、表级锁(Table Lock)

表级锁是 作用在整张表上的锁,也就是说,一旦某个事务对表加锁,其他事务访问该表就会受到限制。

表级锁的特点:

  • 加锁速度快
  • 实现简单
  • 锁粒度大
  • 并发能力较低

MySQL 中表级锁主要包括三种:

  • 显式表锁
  • 元数据锁(MDL)
  • 意向锁

1 显式表锁(LOCK TABLES)

显式表锁是通过 SQL 语句手动对表加锁:

LOCK TABLES table_name READ;
LOCK TABLES table_name WRITE;

释放锁:

UNLOCK TABLES;

1.1 READ 锁(读锁)

LOCK TABLES user READ;

含义:

  • 当前事务可以读取表数据
  • 不允许修改数据
  • 其他事务可以继续获取 READ 锁
  • 其他事务不能获取 WRITE 锁

也就是说:

读读可以并发,读写互斥。

1.2 WRITE 锁(写锁)

LOCK TABLES user WRITE;

含义:

  • 当前事务可以读写表
  • 其他事务既不能读也不能写
  • 直到执行 UNLOCK TABLES

因此 WRITE 锁是 排他锁

2 元数据锁(MDL Lock)

MDL(Metadata Lock)是 MySQL 自动维护的一种锁,不需要手动加锁。

它的作用是:

防止在执行 DML 操作时表结构被修改。

例如:

执行查询:

SELECT * FROM user;

MySQL 会自动添加:MDL 读锁

如果执行:

ALTER TABLE user ADD COLUMN age INT;

MySQL 会添加:MDL 写锁

MDL 写锁会阻塞其他事务的读写操作,从而避免 DDL 与 DML 冲突

在生产环境中,如果一个事务长时间未提交,可能会导致:

ALTER TABLE 一直等待

这往往就是 MDL 锁导致的阻塞问题

3 意向锁(Intention Lock)

意向锁是 InnoDB 在 表级别维护的一种锁标记,用于配合行锁使用。

它的核心作用是:

在事务对某一行数据加锁之前,先在表级别声明加锁意图。

例如:

SELECT * FROM user WHERE id = 1 FOR UPDATE;

InnoDB 会做两件事:

1️⃣ 在表上加 意向排他锁(IX)
2️⃣ 在对应记录上加 行排他锁(X锁)

3.1 意向锁分类

意向锁(Intention Lock)不是只有 IX 一种,而是一个锁的类别,其中包括两种类型:

  • IS(Intention Shared Lock)意向共享锁
  • IX(Intention Exclusive Lock)意向排他锁

 也就是说:

锁类型含义
IS表示事务准备在某些行上加 共享锁(S锁)
IX表示事务准备在某些行上加 排他锁(X锁)

举个例子

1️⃣ 查询加共享锁

SELECT * FROM user WHERE id = 1 LOCK IN SHARE MODE;

InnoDB 会:

表:IS
行:S

2️⃣ 更新数据

UPDATE user SET age = 20 WHERE id = 1;

InnoDB 会:

表:IX
行:X

3.2 为什么需要意向锁?

假设没有意向锁:

当一个事务想给整张表加锁时,就必须扫描整张表,查看是否存在行锁,这样效率非常低。

而有了意向锁之后:

只需要检查表级锁即可判断是否存在行锁。

因此:

意向锁的本质是 用于快速判断表中是否存在行锁的标记

一句话总结:意向锁(Intention Lock)是 InnoDB 在表级维护的一种锁标记,用于表示事务即将在某些行上加锁,其主要类型包括意向共享锁(IS)和意向排他锁(IX)。

二、行级锁(Row Lock)

行级锁是 InnoDB 存储引擎支持的一种锁机制

相比表锁,它的特点是:

  • 锁粒度更小
  • 并发能力更强
  • 更适合高并发系统

行锁锁定的是 一条具体记录,而不是整张表

1 记录锁(Record Lock)

记录锁是最基本的行锁,它只锁定某一条记录。

例如:

SELECT * FROM user WHERE id = 1 FOR UPDATE;

只会锁住:

id = 1 这一条记录

其他记录仍然可以被访问。

记录锁通常分为:

  • S 锁(共享锁)
  • X 锁(排他锁)

它们满足:

读读可以并发
读写互斥
写写互斥

2 间隙锁(Gap Lock)

间隙锁锁住的不是具体记录,而是 索引之间的空隙

例如:

SELECT * FROM user WHERE score > 100 FOR UPDATE;

如果当前数据为:

100
150
200

间隙锁可能锁住:

(100 , +∞)

这样其他事务就 不能插入 score=120 的数据

间隙锁的主要作用是:

防止幻读。

需要注意:

间隙锁 不会锁住已有记录,只锁住区间

3 临键锁(Next-Key Lock)

Next-Key Lock 是:

Record Lock + Gap Lock

也就是说:

既锁住记录,又锁住间隙。

例如:

SELECT * FROM user WHERE age BETWEEN 20 AND 30 FOR UPDATE;

假设表中存在:

20
25
30

InnoDB 可能锁住:

(-∞,20]
(20,25]
(25,30]
(30,+∞)

这样不仅锁住已有记录,还锁住记录之间的间隙。

因此:

Next-Key Lock 可以彻底防止幻读。

到此这篇关于MYSQL中锁的分类与加锁方式小结的文章就介绍到这了,更多相关mysql锁的分类与加锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL的自增主键耗尽的问题解决

    MySQL的自增主键耗尽的问题解决

    当MySQL的自增主键达到INT UNSIGNED上限时,系统会因主键冲突而拒绝新数据插入,本文就来介绍一下MySQL的自增主键耗尽的问题解决,感兴趣的可以了解一下
    2026-03-03
  • MySQL表字段数量限制及行大小限制详情

    MySQL表字段数量限制及行大小限制详情

    这篇文章主要介绍了MySQL表字段数量限制及行大小限制详情,表的行最大的row size会限制字段数量,如果当前row size过大就不能加字段了,更多相关需要的小伙伴可以参考下面文章详情
    2022-07-07
  • mysql数据库中1045错误的解决方法

    mysql数据库中1045错误的解决方法

    这篇文章主要为大家详细介绍了MySQL数据库中1045错误的解决方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • MySQL EXPLAIN 从入门到实战完全指南

    MySQL EXPLAIN 从入门到实战完全指南

    本文详细介绍了MySQL的EXPLAIN工具,该工具可以帮助开发者理解SQL查询的执行计划,从而优化查询性能,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2025-12-12
  • MySQL数据库查询之多表查询总结

    MySQL数据库查询之多表查询总结

    最近遇到了多表查询的需求,也称为关联查询,指两个或更多个表一起完成查询操作,下面这篇文章主要给大家介绍了关于MySQL数据库查询之多表查询的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • mybatis-plus如何使用sql的date_format()函数查询数据

    mybatis-plus如何使用sql的date_format()函数查询数据

    这篇文章主要给大家介绍了关于mybatis-plus如何使用sql的date_format()函数查询数据的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2023-02-02
  • 浅谈MySQL数据库的备份与恢复

    浅谈MySQL数据库的备份与恢复

    MYSQL数据库的备份、恢复等是每一位信息管理人员应必备的能力,因此掌握MYSQL数据库管理的技巧会使您的工作事半功倍,这里我们来简单总结下。
    2017-01-01
  • MySQL不使用子查询的原因及优化案例

    MySQL不使用子查询的原因及优化案例

    对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家详细介绍了MySQL不使用子查询的原因及优化案例,需要的朋友可以参考下
    2025-01-01
  • Mysql 开启Federated引擎的方法

    Mysql 开启Federated引擎的方法

    FEDERATED是其中一个专门针对远程数据库的实现。一般情况下在本地数据库中建表会在数据库目录中生成相应的表定义文件,并同时生成相应的数据文件
    2012-12-12
  • 详解mysql的limit经典用法及优化实例

    详解mysql的limit经典用法及优化实例

    这篇文章详细介绍了mysql的limit经典用法及优化实例,有需要的朋友可以参考一下
    2013-09-09

最新评论