【MySQL | 第九篇】重新认识MySQL锁

在这里插入图片描述

文章目录

  • 9.重新认识MySQL锁
    • 9.1MySQL锁概述
    • 9.2锁分类
      • 9.2.1锁的粒度
      • 9.2.2锁的区间
      • 9.2.3锁的性能
      • 9.2.4锁的级别
    • 9.3拓展:意向锁
      • 9.3.1意向锁概述
      • 9.3.2意向锁分类
      • 9.3.3意向锁作用
        • (1)意向锁的兼容互斥性
        • (2)例子1(意向锁和表级的共享/排他锁互斥)
        • (3)例子2(意向锁和行级的共享锁/排他锁兼容)
        • (4)小结

9.重新认识MySQL锁

9.1MySQL锁概述

  • 锁是计算机协调多个进程或者线程并发访问某一资源的机制
  • 在数据库中除了传统的对计算资源的争抢之外,数据也是供许多用户共享的一种资源,如何保证多线程下的数据一致性是数据库必须解决的一个问题

9.2锁分类

共有四种角度将MySQL锁分类:

  • 锁的粒度:
    • 全局锁
    • 表级锁
    • 行级锁
    • 页级锁
  • 锁的区间:
    • 间隙锁
    • 临建锁
  • 锁的性能:
    • 乐观锁
    • 悲观锁
  • 锁的级别:
    • 共享锁(读锁)
    • 排他锁(写锁/独占锁)

9.2.1锁的粒度

  • 全局锁:锁住数据库中的所有表
  • 表级锁:锁住数据库中的整张表
  • 行级锁:锁住对应的行数据

9.2.2锁的区间

  • 间隙锁

    • 定义:间隙锁用于 锁定一个范围(开区间) 而不是单个行。当事务在范围内的一行上持有锁时,其他事务无法在这个范围内插入新的数据,但是可以在范围之外插入新的数据。
    • 举例:假设一个表中的索引列有序且不重复,事务A持有了某个范围内的间隙锁,这个范围可能是一段索引范围,比如(10,20),这时其他事务无法在这个范围内插入新的行。
  • 临建锁

    • 定义::临建锁是一种结合了行锁和间隙锁的锁类型,它在锁定一个范围时同时锁定了该范围内的行以及范围之间的间隙
    • 举例:考虑一个范围查询,比如查询索引列值在(10,20)之间的行,临建锁会锁定这个范围内的行,同时锁定范围之间的间隙,防止其他事务在这个范围内插入新的行或者改变已有行的值。

9.2.3锁的性能

  • 乐观锁:

    • 定义:乐观锁认为数据在被操作时很少发生冲突,因此在访问数据时不会立即加锁,而是在更新数据时检查数据是否被其他事务修改过,如果没有则更新成功,否则进行回滚或者重试。

    • 举例:在MySQL中,可以使用乐观锁的方式是在更新数据时检查数据的版本号或者时间戳是否与当前操作一致

      UPDATE table_name 
      SET column1 = value1, version = new_version WHERE id = x AND version = old_version;
      
  • 悲观锁:

    • 定义:悲观锁认为数据在被操作时会发生冲突,因此在访问数据之前会先加锁,确保其他事务无法修改该数据,直到当前事务完成操作并释放锁。

    • 举例:在MySQL中,可以使用SELECT … FOR UPDATE语句来获取悲观锁,例如

      SELECT * 
      FROM table_name 
      WHERE condition 
      FOR UPDATE;
      

9.2.4锁的级别

  • 共享锁:

    • 定义:共享锁允许多个事务同时读取同一行数据,但阻止其他事务在该行上获取排他锁;

    • 举例:在 MySQL 中,可以使用 SELECT ... LOCK IN SHARE MODE 或者 SELECT ... FOR SHARE 来获取共享锁,例如

      SELECT * 
      FROM table_name 
      WHERE condition 
      LOCK IN SHARE MODE;
      
  • 排他锁:

    • 定义:排他锁(也称为写锁)阻止其他事务对同一行数据进行读取或写入操作,只有获取了排他锁的事务才能对数据进行修改

    • 举例:在 MySQL 中,可以使用 SELECT ... FOR UPDATE 来获取排他锁,例如

      SELECT * 
      FROM table_name 
      WHERE condition 
      FOR UPDATE;
      

9.3拓展:意向锁

9.3.1意向锁概述

MySQL 中的意向锁(Intention Lock)是一种用于管理表级锁的锁机制,用于在表级别上指示事务将要在表的哪些行上获取锁

意向锁并不是实际的锁,而是一种指示,通常用于协调事务对表级锁的获取,以提高并发性能和降低死锁的风险。

9.3.2意向锁分类

可分为两种类型:意向共享锁和意向排他锁

  • 意向共享锁(Intention Share Lock):

    • 特点:表明事务将要在表的某些行上获取共享锁。当一个事务打算获取某行的共享锁时,会在表级别请求意向共享锁
    • 作用:意向共享锁是为了协调多个事务同时获取共享锁而引入的,在获取共享锁之前,需要先检查是否存在排他锁,以防止与其他事务的排他锁冲突
  • 意向排他锁(Intention Exclusive Lock):

    • 特点:表明事务将要在表的某些行上获取排他锁。当一个事务打算获取某行的排他锁时,会在表级别请求意向排他锁
    • 作用:意向排他锁是为了协调多个事务同时获取排他锁而引入的,在获取排他锁之前,需要先检查是否存在共享锁或其他事务的排他锁,以防止与其他事务的共享锁或排他锁冲突

9.3.3意向锁作用

没有意向锁时,事务在获取表级锁/行级锁之前可能需要频繁地检查整个表,以确定是否有其他事务已经持有了排他锁或共享锁。这会增加系统的开销,降低并发性能。

举例:

事务 A 获取了某一行的排他锁,并未提交:

SELECT * FROM users WHERE id = 6 FOR UPDATE;

事务 B 想要获取 users 表的表锁(共享锁)/行级锁:

LOCK TABLES users READ;

为共享锁与排他锁互斥,所以事务 B 在视图对 users 表加共享锁的时候,必须保证:

  • 当前没有其他事务持有 users 表的排他锁。
  • 当前没有其他事务持有 users 表中任意一行的排他锁

为了检测是否满足第二个条件,事务 B 必须在确保 users表不存在任何排他锁的前提下,去检测表中的每一行是否存在排他锁

很明显这是一个效率很差的做法,但是有了意向锁之后,情况就不一样了:

(1)意向锁的兼容互斥性

特点:多个事务可以对同一张表多个意向排他锁

意向共享锁(IS)意向排他锁(IX)
意向共享锁(IS)兼容兼容
意向排他锁(IX)兼容兼容

意向锁之间是互相兼容的,虽然意向锁和自家兄弟互相兼容,但是它会与普通的排他 / 共享锁互斥

意向共享锁(IS)意向排他锁(IX)
共享锁(S)兼容互斥
排他锁(X)互斥互斥

注意:这里的排他 / 共享锁指的都是表锁!!!

意向锁不会与行级的共享 / 排他锁互斥!!!

(2)例子1(意向锁和表级的共享/排他锁互斥)

回到刚才 users 表的例子:

事务 A 获取了某一行的排他锁,并未提交:

SELECT * FROM users WHERE id = 6 FOR UPDATE;
  • 此时 users 表存在两把锁:users 表上的意向排他锁与 id 为 6 的数据行上的排他锁

事务 B 想要获取 users 表的表锁(共享锁):

LOCK TABLES users READ;
  • 此时事务 B 检测事务 A 持有 users 表的意向排他锁,就可以得知事务 A 必然持有该表中某些数据行的排他锁
  • 事务 Busers 表的加锁请求就会被排斥(阻塞),而无需去检测表中的每一行数据是否存在排他锁
(3)例子2(意向锁和行级的共享锁/排他锁兼容)
  • 意向锁并不会影响到多个事务对不同数据行加排他锁时的并发性

事务 A 获取了某一行的排他锁,并未提交:

SELECT * FROM users WHERE id = 6 FOR UPDATE;
  • 此时 users 表存在两把锁:
    • users 表上的意向排他锁
    • id 为 6 的数据行上的排他锁

事务 B 想要获取 users 表的表锁(共享锁):

LOCK TABLES users READ;
  • 此时事务 B 检测事务 A 持有 users 表的意向排他锁,就可以得知事务 A 必然持有该表中某些数据行的排他锁
  • 事务 Busers 表的加锁请求就会被排斥(阻塞),而无需去检测表中的每一行数据是否存在排他锁

最后事务 C 也想获取 users 表中某一行的排他锁

SELECT * FROM users WHERE id = 5 FOR UPDATE;
  1. 事务 C 申请 users 表的意向排他锁
  2. 事务 C 检测到事务 A 持有 users 表的意向排他锁
  3. 因为意向锁之间并不互斥,所以 事务 C 获取到了 users 表的意向排他锁
  4. 因为id 为 5 的数据行上不存在任何排他锁,最终事务 C 成功获取到了该数据行上的排他锁
(4)小结

意向锁的引入主要是为了提高并发性能。通过引入意向锁,MySQL 可以更有效地管理表级锁,减少了在并发环境下的锁冲突,从而提高了系统的并发处理能力。

在没有意向锁之前,如果一张表里面已经有行锁了此时我们再添加表锁,为了防止表锁和行锁发生冲突,表锁就需要遍历整个表中的数据检查是否有行锁。为了优化表锁检索行锁的过程,我们引入意向锁。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/5444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Flutter】极光推送配置流程(小米厂商通道) 章二

前言 继【Flutter】极光推送配置流程(极光通道/华为厂商/IOS) 章一 并且,我大概率不会去修改第一篇文章的内容。 随着我自己在配置公司的项目的同时,我希望一直更新这个推送系列文章。 在章一配置完后,也是出现了一些问题,所以本…

PHP算命源码_最新测算塔罗源码_可以运营

众筹商城源码 众筹商品平台 商城加共识元富之路 网上商城众筹 前端是编译后的,后端PHP,带商城 运行截图 源码贡献 https://githubs.xyz/boot?app39 部分数据库表 CREATE TABLE ti_shopro_store (id int(11) NOT NULL AUTO_INCREMENT COMMENT ID,nam…

当Kubeflow遇上GPU池化

随着人工智能技术的迅猛发展,AI开发已成为企业创新的重要驱动力。然而,在AI开发过程中,企业面临着诸多挑战,如开发工具的选择和开发资源如何高效利用等。本文将围绕这些挑战,探讨GPU池化如何赋能Kubeflow进行AI开发&am…

实验八智能手机互联网程序设计(微信程序方向)实验报告

请在上一次实验的基础之上完成“手机快速注册”页面、“企业用户注册”页面,并实现点击手机快速注册和企业用户注册后转跳至该页面在“手机快速注册”页面,输入框内输入内容并失去焦点后,下方的按钮会变化 在企业用户注册页面,用户…

【网站项目】木里风景文化管理平台

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

在Linux操作系统中的磁盘分区管理案例

1.在硬盘sdb上创建不同的分区实例练习 Linux操作系统是安装在硬盘sda硬盘中,所以不要轻易动硬盘sda中的文件信息 有如下需求 创建主分区 500M 文件系统 ext4 挂载点 /web 创建主分区 500M 文件系统 ext4 挂载点 /nginx 创建逻辑分区 500M 文件系…

【webrtc】MessageHandler 4: 基于线程的消息处理:以Fake 收发包模拟为例

G:\CDN\rtcCli\m98\src\media\base\fake_network_interface.h// Fake NetworkInterface that sends/receives RTP/RTCP packets.虚假的网络接口,用于模拟发送包、接收包单纯仅是处理一个ST_RTP包 消息的id就是ST_RTP 类型,– 然后给到目的地:mediachannel处理: 最后消息消…

GPT3 终极指南(二)

原文:zh.annas-archive.org/md5/6de8906c86a2711a5a84c839bec7e073 译者:飞龙 协议:CC BY-NC-SA 4.0 第五章:GPT-3 作为企业创新的下一步 当一个新的创新或技术转变发生时,大公司通常是最后一个采纳的。它们的等级结构…

虚拟机安装与配置win7

一、安装镜像 Windows7 64位 ed2k://|file|cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso|3420557312|B58548681854236C7939003B583A8078|/ 建议迅雷下载 二、VMware 安装win7 1.新创自定义虚拟机 2.默认即可 3.iso文件我们自己下载,选择一个空的磁盘 4.…

【记录】Python3| 将 PDF 转换成 HTML/XML(✅⭐⭐⭐⭐pdf2htmlEX)

本文将会被汇总至 【记录】Python3|2024年 PDF 转 XML 或 HTML 的第三方库的使用方式、测评过程以及对比结果(汇总),更多其他工具请访问该文章查看。 文章目录 pdf2htmlEX 使用体验与评估1 安装指南2 测试代码3 测试结果3.1 转 HT…

闪存存储和制造技术概述

闪存存储技术 引言 性能由高到低排序:SLC -> MLC -> TLC -> QLC 根据这个排序读写速度也越来越低,价格越来越便宜 1. SLC SLC(Single-Level Cell,单层单元): SLC 闪存具有最高的性能、耐用性和可…

【专篇】DDR3 SDRAM-01总体介绍

概念 DDR3 SDRAM(Double-Data-Rate 3 Synchronous Dynamic Random-Access Memory,第三代双倍速率同步动态随机存取存储器)是计算机存储技术的一种重要进步,它在前代DDR2 SDRAM的基础上进行了多项改进和优化。以下是DDR3 SDRAM的特点介绍: 双倍速率(DDR):DDR3 SDRAM采用…

c#数据库: 4.修改学生成绩

将4年级的学生成绩全部修改为100分,。修改前的学生信息表如图所示: using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks;namespace StudentUpdate {internal class Program{s…

Ubuntu如何更换 PyTorch 版本

环境: Ubuntu22.04 WLS2 问题描述: Ubuntu如何更换 PyTorch 版本考虑安装一个为 CUDA 11.5 编译的 PyTorch 版本。如何安装旧版本 解决方案: 决定不升级CUDA版本,而是使用一个与CUDA 11.5兼容的PyTorch版本,您可…

c#数据库: 10.调用存储过程查询信息,并显示在窗体上

查询女生信息,并将信息显示在窗体上: 原数据表//右键数据库名,新建查询 ------------- 新建查询窗口,添加新建存储过程Procedure_GetGirls1和查询代码如下 : CREATE PROCEDURE dbo.Procedure_GetGirls1 /*存储过程名称*/ AS SELECT * f…

【docker】Spring Boot3.x 打包 Docker容器

Docker化Spring Boot应用 创建文件夹 demo mkdir democd demo创建Dockerfile # 两个 openjdk 二选一 #FROM openjdk:17-jre-alpineFROM eclipse-temurin:17MAINTAINER chengxuyuanshitang <chengxuyuanshitangXX.com>RUN mkdir -p /workspace/java/demoCOPY demo.ja…

Python 与 TensorFlow2 生成式 AI(五)

原文&#xff1a;zh.annas-archive.org/md5/d06d282ea0d9c23c57f0ce31225acf76 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第十二章&#xff1a;用生成式人工智能玩视频游戏&#xff1a;GAIL 在之前的章节中&#xff0c;我们已经看到如何使用生成式人工智能来生成…

LVGL自定义滑动

触摸和编码器都可以操作 typedef struct {lv_obj_t* obj;int16_t x;int16_t y;int16_t width;int16_t height; }pos_and_size_t;typedef struct {lv_obj_t* obj;lv_coord_t height;lv_coord_t width;lv_coord_t width_pad;lv_coord_t height_pad;lv_coord_t child_widget;lv_co…

Mybatis.net + Mysql

项目文件结构 NuGet下载Mybatis.net相关包&#xff1a;IBatisNet 安装完成后&#xff0c;会显示在&#xff0c;在已安装页面。同时&#xff0c;在管理器中的引用列表中&#xff0c;会多出来两个引用文件 IBatisNet.CommonIBatisNet.DataMapper 安装 Mysql.data。 注意&#xff…