MySQL:表级锁

news/2024/10/16 4:33:40/

表级锁

Table Lock(表锁)是一种数据库锁(Lock)机制,用于控制并发访问数据库表的操作。当一个会话对表进行操作时,会自动获取相应的锁,以确保其他会话无法同时修改该表的数据,从而维持数据库的一致性和完整性。

MySQL中的表级锁(Table-Level Lock)是对整个表进行锁定的一种机制。当表被锁定后,其他事务不能对该表进行写操作,部分情况下也不能进行读操作,具体取决于锁的类型。表级锁的实现简单,但并发性能较低,因为它会锁定整个表,导致其他事务的等待和阻塞。

关于数据库锁机制的详解数据库的锁机制

表级锁的类型

MySQL 的表级锁主要分为以下几种类型:

  1. 表锁(Table Lock)

    • 读锁(Read Lock):也称为共享锁(Shared Lock)(S锁),允许其他事务读取该表,但不允许写入。

    • 写锁(Write Lock):也称为排他锁(Exclusive Lock)(X锁),不允许其他事务读取或写入该表。

  2. 元数据锁(Metadata Lock, MDL)

    • 主要用于避免 DML(数据操纵语言)与 DDL(数据定义语言)之间的冲突。当对表进行增删改查操作时,会自动加上 MDL 读锁;当要对表结构进行变更时,会加上 MDL 写锁。
  3. 意向锁(Intention Lock)

    • 包括意向共享锁(IS)和意向排他锁(IX)。它们主要用于表明事务将来可能需要的锁类型,以减少表锁的判断成本。

加锁语句

使用 LOCK TABLE 语句手动为一个或多个表设置表锁,以确保在事务执行期间其他会话无法对这些表进行读写操作:

sql">LOCK TABLES table_name [AS alias] lock_type [, table_name [AS alias] lock_type]...
sql">-- 为单个表设置表锁
LOCK TABLE table_name READ | WRITE;-- 为多个表设置表锁
LOCK TABLE table1 READ | WRITE,table2 READ | WRITE,...
  • READ 为表设置 共享锁WRITE 为表设置 排他锁
  • 当会话被终止后,无论是正常还是异常终止,表锁都会被 MySQL 自动解除
  • 也可以通过显式的 COMMITROLLBACK 事务来释放锁
注意事项
  • 锁定表之后,其他会话将无法对锁定的表进行读写操作,直到使用 UNLOCK TABLES 释放表锁。

  • 锁定表是一个重型操作,对系统性能有一定影响。

  • 在使用 LOCK TABLES 之前,需要确保没有任何未提交的事务正在使用要锁定的表。

  • 在使用 LOCK TABLES 时,需要小心避免死锁的情况,即多个会话相互等待彼此持有的锁而无法继续执行。

通常情况下,推荐使用隐式锁定来管理并发操作,而不是手动使用 LOCK TABLES 语句。只有在特殊情况下,如需要手动控制表的锁定和并发访问时,才使用 LOCK TABLES

解除表锁

使用 UNLOCK TABLES 将表锁解除:

sql">UNLOCK TABLES;
  • 这条语句会释放当前会话持有的所有表锁。需要注意的是,UNLOCK TABLES后面不能跟表名,也不能只释放指定表的锁。

共享锁

在并发场景中,多个会话可能同时访问同一个数据对象(如表、行等),如果不加以限制,可能会引发一致性问题,例如脏读、不可重复读和幻读等。为了确保数据的一致性和避免并发问题,数据库系统引入了共享锁机制。

共享锁(Shared Lock):共享锁允许多个会话同时对同一个表进行读取操作,这些会话之间不会互相阻塞。

共享锁尤其适用于读取密集型操作,如查询和报表生成;在需要修改数据的操作(例如插入、更新、删除)时,通常会使用排他锁来保证数据的一致性。

特点
  1. 多个对话可以在同一时间获取一个表的共享锁,其他会话无需获取共享锁也可以读取该表数据

  2. 只能读取持有共享锁的表中的数据,不能对其写入,只有共享锁被解除后,才能写入;写入操作会被放入等待队列中,当锁解除后才能执行。可以通过 SHOW PROCESSLIST 指令查看

  3. 其他会话若插入数据,将会报错:

sql">Error Code: 1099. Table 'messages' was locked with a READ lock and can't be updated.
获取共享锁

LOCK IN SHARE MODE 是 MySQL 中的锁定语句,用于在事务中获取共享锁。

语句只在事务中有效,使用时应确保在合适的事务范围内执行

当在一个事务中使用 SELECT 查询语句时,通过添加 LOCK IN SHARE MODE 语句,可以在读取数据的同时对返回的数据集加上共享锁。

sql">START TRANSACTION;  -- 开启一个新事务
SELECT column_list FROM table [WHERE condition]
LOCK IN SHARE MODE;
COMMIT;
示例
sql">-- 会话 A
BEGIN;
SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE;
-- 读取操作 ...-- 会话 B
BEGIN;
SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE;
-- 读取操作 ...

会话 A 和会话 B 通过 LOCK IN SHARE MODE 获取了对表 table_name 的共享锁,它们可以同时读取数据。两个会话之间没有互相阻塞的情况

排他锁

排他锁(Exclusive Lock) 允许一个会话独占地持有对数据对象的锁,其他会话无法同时获取共享锁或排他锁,从而实现了并发写入操作的互斥性。

一个会话持有排他锁,其他会话无法同时对数据对象进行读取操作或写入操作

读写操作会被放入等待队列中,当锁解除后才能执行。可以通过 SHOW PROCESSLIST 指令查看

获取排他锁

FOR UPDATE 是一种在 SQL 查询中使用的锁定语句,用于获取排他锁,确保在事务中对查询结果集进行排他性操作

使用 FOR UPDATE 语句时,数据库会为查询结果集中的每一行都加上排他锁,以防止其他会话对这些行进行修改操作,直到当前事务提交或回滚为止。

sql">BEGIN TRANSACTION
SELECT column_list FROM table [WHERE condition]
FOR UPDATE;
[-- 对查询结果进行修改操作
UPDATE table_name SET column_name = value;]
COMMIT;
示例
sql">-- 会话 A
BEGIN;
SELECT * FROM table_name WHERE ... FOR UPDATE;
-- 写入操作 ...-- 会话 B
BEGIN;
SELECT * FROM table_name WHERE ... FOR UPDATE;
-- 写入操作 ...
-- 会话 A 提交之前,会话 B 在相同的查询条件下无法获取/写入对应的行数据

会话 A 和会话 B 通过 FOR UPDATE 获取了对表 table_name 的排他锁,它们不能同时读取或写入数据。如果会话 A 已经获取了排他锁,则会话 B 需要等待会话 A 释放锁后才能获取排他锁执行相应操作。

局限性和注意事项

  • 表级别的锁粒度较大,当多个会话需要并发操作同一个表时,可能会出现阻塞和资源竞争的情况,降低系统的并发性能。

  • 表锁的粒度较大也导致了锁的冲突概率增加,从而可能导致死锁的发生。死锁是指多个会话相互等待对方持有的锁资源,导致所有会话都无法继续执行。

  • 当一个会话持有排他锁时,其他会话无法并发读取表中的数据,这可能导致读取操作的延迟。

为了避免表级锁可能带来的性能问题和并发冲突,通常还会使用更细粒度的锁机制,如 行级锁页级锁乐观并发控制 等,以提高并发性能和减少锁竞争。具体使用哪种锁机制取决于数据库管理系统的支持和应用的需求。


http://www.ppmy.cn/news/1504711.html

相关文章

拉刀基础知识——拉刀的种类

如前面所说:近期要围绕拉削和拉刀这个话题,分享一些相关的内容,从最基础的知识开始,为此还专门买了本旧书——《拉刀设计》入门学习。废话不多说,直接开始。 拉刀最早由冲头演变而来,用于加工方孔&#xf…

正点原子imx6ull-mini-Linux驱动之Linux 自带的 LED 灯驱动实验(16)

前面我们都是自己编写 LED 灯驱动,其实像 LED 灯这样非常基础的设备驱动,Linux 内 核已经集成了。Linux 内核的 LED 灯驱动采用 platform 框架,因此我们只需要按照要求在设备 树文件中添加相应的 LED 节点即可,本章我们就来学习如…

基于X86+FPGA助力实现电力系统的智能监测与高效管理

电力监控 信迈提供基于Intel平台、Xilinx平台、Rockchip平台、NXP平台、飞腾平台的Mini-ITX主板、Micro-ATX主板、ATX主板、嵌入式准系统/工业整机等计算机硬件。产品算力强大,支持高速存储,提供丰富串口、USB、LAN、PCIe扩展接口、显示接口等I/O接口&am…

typescript 定义类型

type infoType string; let name: infoType "全易"; let location: infoType "北京"; // let age: infoType 18; // 报错 infoType string|number 就不报错了 let job: infoType "开发"; let love: infoType "吃喝玩乐&q…

【系统架构设计师】二十三、通信系统架构设计理论与实践②

目录 二、5G 网络边缘计算 三、存储网络架构 四、软件定义网络架构 五、网络构建关键技术 5.1 网络的高可用性 5.2 IPv4 与 IPv6 融合组网技术 六、网络构建和设计方法 6.1 网络需求分析 6.2 网络技术遴选及设计 6.3 层次化网络模型设计 6.4 网络安全控制技术 6.5 …

Spark-第三周

1.sparkcontext 初始化源码分析 Spark 源码(7) - SparkContext 初始化 源码分析_太与旅 spark源码-CSDN博客 Spark源码学习(一):SparkContext初始化源码分析_spark initialize-CSDN博客 2.任务调度源码分析 job提交 spark 提交job运行…

「Unity3D」自动布局LayoutElement、ContentSizeFitter、AspectRatioFitter、GridLayoutGroup

布局元素与布局控制器 布局元素实现ILayoutElement接口,布局控制器实现ILayoutController接口,后者根据前者的属性控制具体布局——有些布局控制器也是布局元素,即同时实现这两个接口,如LayoutGroup。 public interface ILayout…

tomato-靶机渗透

tomato-靶机 一、安装靶机环境 下载双击.ova文件,写文件名路径导入 打开虚拟机用NAT模式 编辑–>虚拟网络编辑器查看IP段 二、信息收集 1.御剑端口扫描查找该虚拟机的IP 访问网站 扫目录 dirb http://192.168.30.130 收集到目录 /server-status /antibot_im…