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的DELETE删除数据示例详解

    MySQL的DELETE删除数据示例详解

    MySQL的DELETE语句用于从数据库表中删除记录,本文将详细介绍DELETE语句的基本语法、高级用法、性能优化策略以及注意事项,感兴趣的朋友跟随小编一起看看吧
    2024-12-12
  • MySQL数据库聚合查询和联合查询详解

    MySQL数据库聚合查询和联合查询详解

    聚合查询就是在一个表里通过聚合函数进行查询操作,通常是求和,求平均值等操作,这篇文章主要介绍了MySQL聚合查询和联合查询的相关资料,需要的朋友可以参考下
    2024-03-03
  • mysql中over partition by的具体使用

    mysql中over partition by的具体使用

    在数据库中,我们经常需要对数据进行分组排序等操作,MySQL的over partition by可以帮助我们更方便地进行这些操作,本文主要介绍了mysql中over partition by的具体使用,感兴趣的可以了解一下
    2024-02-02
  • MySQL创建和删除数据库的命令及相关PHP脚本的操作方法

    MySQL创建和删除数据库的命令及相关PHP脚本的操作方法

    这篇文章主要介绍了MySQL创建和删除数据库的命令及相关PHP脚本的操作方法,这里主要讲述Linux中在mysqladmin下的命令操作,需要的朋友可以参考下
    2015-11-11
  • Windows XP系统安装MySQL5.5.28图解教程

    Windows XP系统安装MySQL5.5.28图解教程

    很多朋友在winxp系统中开发php等,需要安装mysql数据库,这里简单介绍下,如何在xp下安装mysql软件,其实跟其它系统都差不多,主要是软件对系统的兼容性
    2013-05-05
  • MySQL的使用中实现读写分离的教程

    MySQL的使用中实现读写分离的教程

    这篇文章主要介绍了MySQL的使用中实现读写分离的教程,文中分别介绍了mysql-proxy与mysqlnd_ms的使用,需要的朋友可以参考下
    2015-12-12
  • 关于MySQL的整型数据的内存溢出问题的应对方法

    关于MySQL的整型数据的内存溢出问题的应对方法

    这篇文章主要介绍了关于MySQL的整型数据的内存溢出问题的应对方法,作者还列出了MySQL所支持的整型数据的存储空间支持大小,需要的朋友可以参考下
    2015-05-05
  • MySQ中出现幻读问题的解决过程

    MySQ中出现幻读问题的解决过程

    文章解析MySQL InnoDB通过MVCC与间隙锁机制在可重复读隔离级别下解决幻读,确保事务一致性,同时指出性能影响及乐观锁等替代方案,帮助开发者优化数据库应用
    2025-08-08
  • 宝塔面板mysql无法启动问题的分析和解决

    宝塔面板mysql无法启动问题的分析和解决

    在使用宝塔linux面板一键安装LNMP的是,数据库mysql始终无法启动,查查找找用了几个小时,问题终于解决了,下面这篇文章主要给大家介绍了关于宝塔面板mysql无法启动问题的分析和解决方法,需要的朋友可以参考下
    2023-04-04
  • Mysql删除重复的数据 Mysql数据去重复

    Mysql删除重复的数据 Mysql数据去重复

    这篇文章主要介绍了Mysql删除重复的数据 Mysql数据去重复,需要的朋友可以参考下
    2016-08-08

最新评论