MySQL中行级锁和表级锁的区别小结

 更新时间:2025年08月01日 11:07:00   作者:Victor356  
MySQL中的行级锁和表级锁是两种不同的锁机制,它们在并发控制和锁粒度方面有显著的区别,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧

MySQL 中的行级锁和表级锁是两种不同的锁机制,它们在并发控制和锁粒度方面有显著的区别。了解这两种锁的区别及其使用场景,有助于优化数据库性能并确保数据一致性。以下是对行级锁和表级锁的详细解析,并结合代码示例来帮助理解。

一、行级锁 vs 表级锁

1. 行级锁(Row-level Locks)

  • 粒度:行级锁锁定的是表中的单个行。
  • 并发性:行级锁具有较高的并发性能,因为不同事务可以并发地修改不同的行。
  • 开销:管理行级锁的开销较高,因为需要跟踪每一行的锁状态。
  • 使用场景:适用于需要高并发读写操作的场景。

2. 表级锁(Table-level Locks)

  • 粒度:表级锁锁定的是整个表。
  • 并发性:表级锁的并发性能较低,因为一个事务锁定整个表后,其他事务不能同时对该表进行任何读写操作。
  • 开销:管理表级锁的开销较低,相对于行级锁而言更简单。
  • 使用场景:适用于读多写少的场景,如报表查询等。

二、InnoDB 中的行级锁

InnoDB 存储引擎支持行级锁,这使得它适用于高并发的事务处理。

1. 共享锁(S-lock)

多个事务可以同时读取同一行,但不能修改。

START TRANSACTION;

-- 获取共享锁
SELECT * FROM employees WHERE id = 1 LOCK IN SHARE MODE;

-- 完成事务
COMMIT;

2. 排它锁(X-lock)

一个事务获取排它锁后,其他事务不能读取或修改该行。

START TRANSACTION;

-- 获取排它锁
SELECT * FROM employees WHERE id = 1 FOR UPDATE;

-- 完成事务
COMMIT;

三、MyISAM 中的表级锁

MyISAM 存储引擎只支持表级锁。

1. 读锁(共享锁)

多个客户端可以同时读取表,但不能写入。

LOCK TABLES employees READ;

-- 在锁定的表上执行读操作
SELECT * FROM employees;

-- 释放锁
UNLOCK TABLES;

2. 写锁(排它锁)

一个客户端获取写锁后,其他客户端不能读取或写入该表。

LOCK TABLES employees WRITE;

-- 在锁定的表上执行写操作
INSERT INTO employees (name, department_id) VALUES ('Alice', 1);

-- 释放锁
UNLOCK TABLES;

四、使用示例

1. 行级锁示例

假设有一个 employees 表,我们使用 InnoDB 存储引擎,并展示行级锁的使用。

CREATE TABLE employees (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    department_id INT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

INSERT INTO employees (name, department_id) VALUES ('Alice', 1), ('Bob', 2);

两会话并发更新不同的行:

  • 会话 1
START TRANSACTION;
UPDATE employees SET name = 'Charlie' WHERE id = 1;
-- 保持事务未提交
  • 会话 2
START TRANSACTION;
UPDATE employees SET name = 'Dave' WHERE id = 2;
-- 保持事务未提交

这种情况下,两会话可以并发执行,因为它们修改的是不同的行。

2. 表级锁示例

假设有一个 employees 表,我们使用 MyISAM 存储引擎,并展示表级锁的使用。

CREATE TABLE employees (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    department_id INT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=MyISAM;

INSERT INTO employees (name, department_id) VALUES ('Alice', 1), ('Bob', 2);

两会话并发更新表:

  • 会话 1
LOCK TABLES employees WRITE;
UPDATE employees SET name = 'Charlie' WHERE id = 1;
-- 保持锁未释放
  • 会话 2
-- 会被阻塞,直到会话 1 释放锁
LOCK TABLES employees WRITE;
UPDATE employees SET name = 'Dave' WHERE id = 2;

这种情况下,会话 2 会被阻塞,直到会话 1 释放锁,因为 MyISAM 使用的是表级锁。

五、意向锁

InnoDB 还支持意向锁(Intent Locks),这是表级锁和行级锁之间的一种协调机制。意向锁分为意向共享锁(IS)和意向排它锁(IX)。

  • 意向共享锁(IS-lock):事务打算在某些行上加共享锁时,先在表级加意向共享锁。
  • 意向排它锁(IX-lock):事务打算在某些行上加排它锁时,先在表级加意向排它锁。

意向锁是由 InnoDB 自动管理的,不需要显式加锁。

六、总结

行级锁和表级锁是 MySQL 中两种重要的锁机制,它们在锁粒度和并发控制方面有显著的区别:

  • 行级锁:粒度较小,适合高并发读写操作,但管理开销较高。InnoDB 存储引擎支持行级锁。
  • 表级锁:粒度较大,适合读多写少的场景,管理开销较低。MyISAM 存储引擎使用表级锁。

通过合理选择和使用锁机制,可以有效提高数据库的并发性能和数据一致性。理解和掌握这些锁机制的细节,有助于在设计和优化数据库时做出更好的决策。

到此这篇关于MySQL中行级锁和表级锁的区别小结的文章就介绍到这了,更多相关MySQL 行级锁和表级锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mysql日期date型和int型互换的方法

    mysql日期date型和int型互换的方法

    下面小编就为大家带来一篇mysql日期date型和int型互换的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • MySQL如何实现负载均衡功能

    MySQL如何实现负载均衡功能

    这篇文章主要介绍了MySQL如何实现负载均衡功能,学习过数据库的朋友们都会知道MySQL,那么如何在MySQL下实现负载均衡功能呢?本文就将为大家细致地介绍一下
    2019-06-06
  • 一文详解如何在MySQL中处理JSON数据

    一文详解如何在MySQL中处理JSON数据

    在当今的大数据时代,JSON作为一种轻量级的数据交换格式,被广泛应用于Web应用的数据传输,随着MySQL 5.7的发布,MySQL引入了对JSON数据类型的支持,本文将详细介绍如何在MySQL中处理JSON数据,并提供示例,需要的朋友可以参考下
    2024-08-08
  • MySQL数据库崩溃问题的检测与解决方法

    MySQL数据库崩溃问题的检测与解决方法

    数据库崩溃问题可能会对系统的可用性和数据的完整性造成严重影响,这篇文章主要为大家详细介绍了MySQL如何解决数据库崩溃问题,需要的小伙伴可以了解下
    2025-07-07
  • MySQL使用C语言连接完整代码样例

    MySQL使用C语言连接完整代码样例

    这篇文章主要介绍了如何使用C语言连接MySQL数据库,包括安装MySQL连接库、初始化MySQL、连接数据库、执行SQL查询、获取查询结果、关闭连接等步骤,并提供了完整的代码示例,需要的朋友可以参考下
    2025-03-03
  • MySQL主从同步诊断show slave status 卡住的深度排查与解决方案(最新推荐)

    MySQL主从同步诊断show slave status 卡住的深度排查与解决方案(最新推荐)

    在 MySQL主从架构的日常运维中,show slave status是监控同步状态的核心命令,本文结合源码分析与调试实践,揭示其背后的锁竞争机制,并提供系统性的排查与优化方案,感兴趣的朋友一起看看吧
    2025-06-06
  • MySQL创建数据库和创建数据表

    MySQL创建数据库和创建数据表

    MySQL 是最常用的数据库,在数据库操作中,基本都是增删改查操作,简称CRUD。但是,这篇文章主要介绍了数据库和数据表如何创建,想详细了解的小伙伴可以参考阅读一下
    2023-03-03
  • linux centos7安装mysql8的教程

    linux centos7安装mysql8的教程

    这篇文章主要介绍了linux centos7安装mysql8的教程,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • MySQL 中 ROW_NUMBER() 函数最佳实践

    MySQL 中 ROW_NUMBER() 函数最佳实践

    MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重、TopN等需要精确顺序控制的场景,本文给大家介绍MySQL中ROW_NUMBER()函数,感兴趣的朋友一起看看吧
    2025-06-06
  • MySQL存储全角字符和半角字符的区别

    MySQL存储全角字符和半角字符的区别

    这篇文章主要介绍了MySQL存储全角字符和半角字符的区别的相关资料,需要的朋友可以参考下
    2017-05-05

最新评论