【Mysql高级】【第十五章】【锁】

2023-11-05

1.概述

事务的隔离性由锁来实现

在这里插入图片描述

2.Mysql并发实务访问相同记录

并发事务访问相同记录的情况大致可以划分为3种:

2.1 读-读

在这里插入图片描述

2.2 写-写

在这里插入图片描述
在这里插入图片描述
锁结构和事务是一一对应的,有几个事务,就会生成几个锁结构,如果该记录还有别的事务要进行操作,会对别的事务也建立锁结构!

锁的生成
在这里插入图片描述

事务T1 提交之前
在这里插入图片描述

事务t1 提交之后
在这里插入图片描述

小结
在这里插入图片描述

2.3 读-写或者写-读

在这里插入图片描述

2.4 并发问题的解决方案

(1)读MVCC ,写加锁

在这里插入图片描述

(2)读和写都加锁

  • 场景:读取的数据必须是最新数据
    在这里插入图片描述
  • 脏读问题:B事务先对记录x进行修改,然后A事务去读取记录x,只要B还没提交,A就不能读取记录x;A读不到B未提交的数据
  • 不可重复读:A事务先读取读记录x,然后B事务想要对x进行修改,此时B就必须等待A事务结束,才能写;
  • 幻读:事务A读取了一个范围的记录,然后B事务向该范围内做了增删记录

小结

在这里插入图片描述

3.锁的不同角度分类

https://www.bilibili.com/video/BV1iq4y1u7vj?p=174
在这里插入图片描述

3.1 从数据操作的类型划分:读锁、写锁

在这里插入图片描述

额外说明:

  • 本质上来说是没有读锁和写锁的,只有排它锁和共享锁;
  • 读操作而言默认是共享锁,但是也可以给读操作上排它锁
  • 写操作就必须是排它锁

0.行级别x锁 和 s锁的兼容性问题

在这里插入图片描述
不管是现有读锁还是写锁,只要有写锁参与都会被阻塞;

1.锁定读

读操作加S锁

在这里插入图片描述

读操作加X锁

在这里插入图片描述

演示1. 两个共享锁

在这里插入图片描述

演示2: 先加共享锁,后加排它锁

在这里插入图片描述

演示3: 先加排它锁,后加共享锁

在这里插入图片描述

8.0 新特性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 写操作

宏观来看,写操作就是加X锁 ;
细节来看,update和delete操作是真正的加排他锁;insert操作只是加隐式锁;
在这里插入图片描述

3.2 从数据操作的粒度划分:表级锁、页级锁、行锁

锁粒度越小,并发度越高;但是同时,管理锁消耗的资源就越多!
在这里插入图片描述

1. 表锁

在这里插入图片描述

(1)表级别S锁和X锁

InnoDB 下的元数据锁

在这里插入图片描述

InnoDB 下表锁

在这里插入图片描述

如何给表上锁演示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

表锁下的 读写并发演示

在这里插入图片描述
上面所说的自己,就是给表上锁的事务;

(1) 表级别读锁
在这里插入图片描述
在这里插入图片描述

(1) 表级别写锁
在这里插入图片描述
在这里插入图片描述

(2)意向锁

意向锁是表锁

在这里插入图片描述

意向锁要解决的问题

在这里插入图片描述

  • 如果事务A给数据表中某些记录上了共享锁,会自动给该数据表添加意向共享锁
  • 如果事务A给数据表中某些记录上了排他锁,会自动给该数据表添加意向排他锁

如何添加意向锁

在这里插入图片描述

举例

在这里插入图片描述
意向锁IX和表级S锁互斥
在这里插入图片描述
事务A给表teacher的某行上了排它锁,自动给表上了意向排它锁IX,此时别的事务想要给此表上表级读锁和表级写锁都会被阻塞!

在这里插入图片描述

总结

  • 意向锁是表级锁,是InnoDB引擎自动生成的;
  • InnoDB支持多粒度锁,特定场景下, 表级锁(意向锁)和行级锁共存;
  • 意向排它锁IX,意向共享锁IS
  • 意向锁之间是不互相排斥的;
  • 意向锁和行级锁也是不互相排斥的(和第二条一个意思=> 意向锁和行锁共存)
  • 表级锁意向锁 之间的排斥规则 和读写锁的排斥规则是一样的
  • 意向锁在保证并发性的前提下,实现了行锁和表锁共存 并且 满足事务隔离性 的要求
(3)自增锁

https://www.bilibili.com/video/BV1iq4y1u7vj?p=176&spm_id_from=pageDriver

自增约束字段的插入演示

在这里插入图片描述

三种插入模式讲解

在这里插入图片描述
在这里插入图片描述

针对自增锁并发性低下的三种锁定模式

(1)传统模式
在这里插入图片描述
传统模式下,只要是insert 语句就要持有AUTO-INC锁才能执行;否则排队阻塞;

(2)连续锁定模式

  • 这种模式优化了 插入已知行数的场景;
  • 对于insert xx select xx from 这种仍然需要AUTO-INC锁;
  • 而对于插入行数已知的insert 语句来说,在执行的时候,直接获取行数,表示要插入这么多行先占位!不需要等数据全部插入进来,占好位置后就可以将AUTO-INC锁释放了
    在这里插入图片描述
    (3)锁定模式

在这里插入图片描述

(4) 元数据锁(MDL锁)

在这里插入图片描述
在这里插入图片描述

2.行级锁

  • 只有InnoDB支持行级锁
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

(1)记录锁

在这里插入图片描述
在这里插入图片描述

记录锁的特点就是锁住表中已有的记录;

(2)间隙锁

在这里插入图片描述

由于是间隙锁,因此间隙读锁、间隙写锁没有本质区别;不影响别的事务继续加gap锁:
在这里插入图片描述
这里上锁并非是给某个值上锁,而是给区间(3,8) 上锁;

间隙锁会阻碍insert:
上面锁住了(3,8),因此这里插入6是插不进去的
在这里插入图片描述
如果在最后一行后面上锁,锁区间就是最后一行到正无穷:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

间隙锁可能会造成死锁

如下图所示:
在这里插入图片描述

第一步:在事务A中,给(3,8)区间上间隙读锁;
第二步:在事务B中,给(3,8)区间上间隙读锁;
第三步:在事务B中,在(3,8)区间插入一条记录,被阻塞
第四步:在事务A中,在(3,8)区间插入一条记录,报错,错误日志:产生死锁;

在这里插入图片描述

  • 事务A持有id=1的写锁
  • 事务B持有id=2的写锁
  • 事务A想要获取id=2的写锁,被阻塞
  • 事务B想要获取id=1的写锁,被阻塞

死锁解决方案:

  1. 等待超时
  2. 让步,让最后一个产生死锁的事务回滚(即事务结束),从而事务B可以顺利执行;
(3) 临键锁(Next-key_lock)

https://www.bilibili.com/video/BV1iq4y1u7vj?p=178

间隙锁是开区间,临建锁是闭区间
在这里插入图片描述
临建锁的写法:在这里插入图片描述
在这里插入图片描述

(4) 插入意向锁

在这里插入图片描述

插入意向锁互不排斥:
在这里插入图片描述
在这里插入图片描述

3.页锁

在这里插入图片描述

3.3 从对待锁的态度划分:乐观锁、悲观锁

1.悲观锁

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.乐观锁

在这里插入图片描述
(1)版本机制实现乐观锁
在这里插入图片描述
update 操作会先读取该记录

事务A:

  • 先读,读的时候版本是1
  • 然后进行update,update的时候还是1,说明在读后没有别的事务修改过他
  • 做完修改后,将version + 1

事务B过来:

  • 读是2
  • 进行修改,version也是2,则可以进行修改。
    读和写之间没有别的事务修改它,相当于保证了读和修改的原子绑定

针对的场景

事务A

  • 读的时候,版本是1

事务B

  • 读的时候,版本也是1
  • 修改了,版本变为2

事务A

  • 修改 update xx where version = 1 发现没有了,修改失败;此时再次查询,发现version变成2了,再对version = 2进行修改

(2) 时间戳机制
在这里插入图片描述

在这里插入图片描述
从秒杀案例2看出:
第一次是读,第二次update也是读,也就是说必须保证写的时候版本和读的时候一致才能进行修改;两次读!!!

读写分离场景: 读从机,写主机
在这里插入图片描述
强制读主机,读写保持一致!

高并发场景
在这里插入图片描述

  • 1、多个事务查询某条记录 version = 1;
  • 2、事务A,进行修改 version =2;
  • 3、其他事务再进行修改,发现version不一致了,因此修改失败

在这里插入图片描述

3.4 按照加锁方式进行分类

https://www.bilibili.com/video/BV1iq4y1u7vj?p=180

1.隐式锁

场景1:Insert

  • 事务A,插入一条记录,此时是不加锁的;还未提交
  • 事务B进来了,进行查询,此时会对A插入的记录进行上锁,因此事务B无法访问到;

特点:懒加载;只有被别的事物要访问的时候才会上锁
目的:防止事务A插入的数据在还未提交时,被别的事务访问到;

场景2:插入意向锁

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Mysql高级】【第十五章】【锁】 的相关文章

  • 为通用字符选择表排序规则

    我正在开发一个需要存储通用字符的后端 我选择了utf8mb4用于此目的的表编码 我还必须选择表格排序规则 最直接的选择是选择utf8mb4 general ci表整理 除了一般的排序规则之外 还有大约20种其他排序规则可供选择 更具体的排序
  • 显示多个表的账户余额

    我有以下两个表 其中存储有关贷记和借记记录的信息 couponCr 表包含 voucherType voucherPrefix voucherNo crparty cramount SALES S 1 1 43000 SALES S 2 1
  • 当列的数据类型为 int 时,如何用字符串替换 null

    我有一个包含 3 列的表和如下示例数据 所有列都是数据类型int 我有这个查询 select foodid dayid from Schedule 我要更换dayid用字符串 ifdayid null 为此我尝试了这个查询 select f
  • Mysql 连接到服务器:用户 root@localhost 的访问被拒绝

    edit9 是否有可能我只是缺少文件夹的一些权限 我真的非常非常感谢更多的建议 edit3 由于这篇文章没有得到足够的回复 而且这绝对是至关重要的 我尽快完成这件事 我重建了我的帖子以显示我认为到目前为止我已经扣除的内容 注意 通过许多不同
  • 更新或插入 MySQL Python

    如果记录已存在 我需要更新一行 如果不存在 我需要创建一个新记录 我理解 ON DUPLICATE KEY 将使用 MYSQLdb 完成此操作 但是我无法使其正常工作 我的代码如下 cursor database cursor cursor
  • 将两个sql查询合并为一个查询

    如何组合以下 2 个查询以便获得两列 PAYMODE 和付款类型 两个查询都很相似 并且针对同一个表 将两个 sql 查询合并为一个查询 这样我就不需要执行两个单独的查询 SELECT ETBL DESC TXT as PAYMODE FR
  • 单向关系和双向关系的区别

    我想知道这两个词是什么意思 我遇到他们是在教义的文档 http www doctrine project org documentation manual 2 0 en association mapping 但我不明白他们的意思 这与常见
  • 在 while 循环内查询可以吗?

    我在一个数据库中有两个表 我正在查询第一个表限制 10 然后循环结果 在 while 循环内 我使用第一个查询中的数据作为参数再次执行另一个查询 以下是该脚本的示例
  • 如何重命名 SQL Server 中名称中带有方括号的内容?

    我的一张桌子上有一列 周围有方括号 Book Category 我想重命名为Book Category 我尝试了以下查询 sp rename BookPublisher Book Category Book Category COLUMN
  • PDO 库比本机 MySQL 函数更快吗?

    我已经阅读了几个与此相关的问题 但我担心它们可能已经过时 因为自这些问题得到解答以来 更新版本的 PDO 库已经发布 我编写了一个 MySQL 类 它构建查询并转义参数 然后根据查询返回结果 目前这个类正在使用内置的mysql函数 我很清楚
  • 获取jdbc中表依赖顺序

    我在 MySQL 数据库中有一组表 A B C D 依赖关系如下 B gt C gt A 和 D gt A 也就是说 A 有一个 PrimaryKey C 有一个外键指向 A 的主键 B 有一个外键指向 C 的主键 类似地 D 有一个外键指
  • 如何更改 Amazon Redshift 中的默认时区?

    默认情况下将时间戳列设置为 SYSDATE 将其存储为UTC 是否可以更改时区 以便 SYSDATE 将日期和时间存储到不同的时区 到目前为止 我已经检查了SET http docs aws amazon com redshift late
  • 我应该保留远程数据库的本地副本吗?

    我正在开发一个应用程序 基本上允许人们创建 加入和管理其他人的群组 群组内的人也可以互相发送消息 我一直在想哪条路会更好 保留包含所有信息的远程数据库 包括发送给用户和从用户发送的消息 并让应用程序在每次需要信息时查询服务器 甚至是它以前见
  • _mysql_connector.MySQLInterfaceError:命令不同步;您现在无法运行此命令 python msql.connector

    我有一个功能 您可以在下面看到 如果运行此函数 我将收到您在标题中看到的错误 您能帮助我吗 不久前我能够用锁解决这个问题 但现在它们不起作用 我知道这与我的连接有关 但我不知道如何解决这个问题 def insertNewValues sel
  • 安全转义表名/列名

    我在 php 中使用 PDO 因此无法使用准备好的语句转义表名或列名 以下是我自己实现它的万无一失的方法 tn str replace REQUEST tn column str replace REQUEST column sql SEL
  • MySQL INSERT 无需指定每个非默认字段(#1067 - “表”的默认值无效)

    我已经见过好几次了 我有一台服务器允许我插入一些值 而无需指定其他值 如下所示 INSERT INTO table SET value a a value b b value c 是一个没有设置默认值的字段 但在这里工作正常 当脚本移动到新
  • 使用 Laravel Fluent 查询生成器从多个表中进行选择

    我正在重写一些 PHP MySQL 来与 Laravel 一起使用 我想做的一件事是使数据库查询更加简洁使用 Fluent 查询生成器 http laravel com docs database fluent但我有点迷失 SELECT p
  • 从本地 html/javascript 网站插入 mySQL 数据库

    我正在尝试做什么 我的程序的目的是插入数据local HTML JS网站变成online 非本地 mySQL数据库 到目前为止我尝试过的 我试图用来实现此目的的原始方法是让我的本地网站使用 javascript 通过在线发布数据PHP文件
  • 更新查询增量字段加上 1 codeigniter 函数 [重复]

    这个问题在这里已经有答案了 我想在 codeigniter 项目中将字段值增加到当前值加 1 所以 我做了一个功能 但它不起作用 我的职能是 function increse field by 1 table name fieldToInc
  • MySQL ALTER TABLE 挂起

    我知道这个问题已经被问过好几次了 但我的问题发生在我刚刚创建的表上 它只有 10 列和 1 行 因此 与通常的挂起问题不同 这不是具有大量数据的大表的情况 但它仍然挂着 这是我正在运行的 SQL ALTER TABLE db Search

随机推荐

  • Zookeeper 基本数据模型

    介绍 ZooKeeper是一个树形结构 类似于前端开发中的tree js组件 ZooKeeper的数据模型也可以理解为linux unix的文件目录 usr local 每个节点都称为znode 它可以有子节点 也可以有数据 每个节点分为临
  • 正则表达式-分组与后向引用

    前文中 已经总结了正则表达式中的常用字符 次数匹配 位置匹配等 这篇文章中 我们来了解一下正则中的 分组 与 后向引用 什么是分组 什么是后向引用 我们慢慢聊 先来说说什么是分组 算了 思考了半天 我也不知道从何说起 先看个示例吧 根据示例
  • 对NetBackup 问题进行故障排除的步骤

    错误消息通常是指出哪里出现故障的手段 如果在界面上没有看到错误消息 但仍怀疑有问题 请检查报告和日志 NetBackup提供了各种报告和日志记录工具 这些工具可提供错误消息 直接为您指出解决方案 日志还可显示什么运行良好以及当发生问题时Ne
  • html设置 元素最小宽度,css如何让元素宽度自适应屏幕大小

    如今 手机的快速发展使得越来越多的人开始使用手机上网 那么就会出现一个问题 如何才能让PC端的网页在手机上正常显示 让元素能够自动适应不同的屏幕大小呢 css如何让元素宽度自适应屏幕大小 1 在网页代码的头部 加入一行viewport元标签
  • Unity中SLua、Tolua、XLua和ILRuntime效率评测

    Unity脚本效率评测 对SLua Tolua XLua和ILRuntime四个脚本插件进行效率测试 对框架脚本进行选型 本文项目 https github com cateatcatx UnityScriptPTest tolua htt
  • Apache Shiro(三)——Spring Boot 与 Shiro的 整合

    在了解了Apache Shiro的架构 认证 授权之后 我们来看一下Shiro与Web的整合 下面以Spring Boot为例 介绍一下Spring Boot 与 Shiro的 整合 一 创建一个Spring Boot项目 可以使用IDEA
  • asio(十二)、 异步tcp、udp服务器

    官网教程 https think async com Asio asio 1 26 0 doc asio tutorial tutdaytime7 html asio 异步tcp udp服务器 int main try asio io co
  • 【vue】vue3中状态管理Pinia(Vuex5)使用快速上手

    Pinia和Vuex一样都是是vue的全局状态管理器 其实Pinia就是Vuex5 只不过为了尊重原作者的贡献就沿用了名字Pinia 关于vuex的介绍可以查看我之前的文章前端状态管理之Vuex全解析 一 安装 npm i pinia S
  • 好文转载 Elasticsearch扫盲篇

    Elasticsearch扫盲篇 编程芝士 于 2023 05 01 22 29 09 发布 507 收藏 4 分类专栏 Elasticsearch 文章标签 elasticsearch 数据库 大数据 原力计划
  • Android开发 指纹识别

    1 添加指纹识别权限
  • Java Map集合知识点整理(疯狂Java讲义读书笔记)

    JDK文档 http tool oschina net apidocs apidoc api jdk zh Map Map用于保存具有映射关系的数据 因此Map集合里保存着两组值 一组值用于保存Map中的Key值 另一组值用于保存Map中的
  • VSCode 集成chatGPT插件

    VSCode 是一款常用的编辑器 可以通过安装插件来扩展其功能 ChatGPT 是一款基于 OpenAI 的 GPT 3 语言模型的聊天机器人插件 可以让 VSCode 具备聊天机器人的功能 要在 VSCode 中集成 ChatGPT 插件
  • qt下实现文件的拖拽打开

    引言 此文用于记录按下鼠标左键不放 拖动文件到程序中打开 该示例中只设置了可以拖动的文件类型为 h cpp txt这三种文件类型 程序运行的效果 示例 下面是具体的实现 项目的结构 具体的实现代码 如下 main cpp include d
  • 网络层之IP协议详解

    网络层 说简单点 就是在复杂的网络环境中确定一个合适的路径 我们来了解一下网络层中一个重要的协议 IP协议 IP协议 1 概念 IP协议是TCP IP协议簇中的核心协议 也是TCP IP的载体 所有的TCP UDP ICMP及IGMP数据都
  • 自定义期间查询数据库

    Python连接数据库匹配 import pandas as pd import numpy as np import pymysql import datetime 连接mysql conn pymysql connect host xx
  • KyLin的网页界面使用

    1 美图 上一篇 http blog csdn net qq 21383435 article details 75198823 1 根据上一张分析的内容得知 涉及到的字段是 pro表的 字段 ID 商品名称 价格 购买数量 付款 类别ID
  • 快速基于nodeJS+vue+vuex+mysql+redis建立一个后台管控系统

    structure admin structure admin是一个后台管控系统的架子 技术栈 nodeJS vue vuex mysql redis 前端使用vue的element ui的组件库 后端使用nodeJS的服务 数据库mysq
  • 求一行字符串的长度。(C语言)

    代码 include
  • hadoop集群搭建

    文章目录 一 基本配置 所有节点 一 配置静态网络 二 修改主机名和修改host文件 三 禁用SELINUX 四 关闭防火墙 并取消开机自启动 五 配置NTP时间同步 集群所有节点 六 下载一下vim编辑器 七 安装JDK1 8 八 创建h
  • 【Mysql高级】【第十五章】【锁】

    锁 1 概述 2 Mysql并发实务访问相同记录 2 1 读 读 2 2 写 写 2 3 读 写或者写 读 2 4 并发问题的解决方案 3 锁的不同角度分类 3 1 从数据操作的类型划分 读锁 写锁 0 行级别x锁 和 s锁的兼容性问题 1