mysql面试(七)

前言

本章节列出了mysql在增删改查的时候,分别会涉及到哪些锁类型,又是如何交互的。
这个章节也是mysql面试基础系列的最后一章,后面准备更新redis数据类型和分布式锁相关问题。如果各位看官有什么问题的话,可以留言。

之前我们也有说关于多事务并发,会出现三种情况:脏读、不可重复读、幻读
对应的解决手段呢,分四个隔离级别:

  • 在Read uncommitted 读未提交隔离级别下, 脏读 、 不可重复读 、 幻读 都可能发生。
  • 在 Read committed 读已提交隔离级别下, 不可重复读 、 幻读 可能发生, 脏读 不可以发生。
  • 在 Repeatable Read 可重复读隔离级别下, 幻读 可能发生, 脏读 和 不可重复读 不可以发生。
  • 在 Serialiazble 串行化隔离级别下,上述问题都不可以发生。

那么实现这些隔离级别的手段是不太一样的。

读已提交很简单,事务提交之后才可以读取。

实现可重复读主要手段是MVCC机制,这个在之前我们也详细讲过具体的实现逻辑了

串行化这种最严谨的隔离级别,简单理解的话就是如果多个事务操作同一条数据,无论是读、写,都要一个个排队来执行,那如何实现这个排队执行呢,就要引入这个锁的概念了。

每当一个事务想要来操作这个数据的时候,就会生成一把锁

总的来说,锁这个概念就是用于公共资源的并发控制

分类

  • 共享锁:share lock 一般称为S锁,或者称为读锁,给一条数据加了这个锁之后,其他事务也可以来加这个S锁来读,但是不能写。
  • 独占锁:exclusive 一般称为X锁,或者称为写锁,当数据被加了这个锁之后,其他事务不可以写也不可读。
  • 意向锁:IS或者IX,当事务给记录加了行锁之后,会在表级别加上对应的意向锁,告知其他事务。还有一种是行级别的意向锁。后面细说

PS:只有S锁和S锁可以相互兼容,S锁与X锁,还有X锁与X锁之间都是互斥的。

一致性读取

这种读取方式也称为快照读,是一种无锁的读取方式,主要就是在MVCC机制中运用的。不会给任何记录加锁,是通过版本来控制同一个事务中多次读取的数据保持一致。详细可以回到上面看看。

锁定读

又叫做当前读,实现方式主要是为相关的记录加上对应的锁,防止其他事务的影响。 而加的锁又有两种类型,一种可以加S锁,lock in share mode,这时候其他事务也可以来读,但是不能写。
另一种是for update,加的是X锁,这时候其他事务不能写,也不能读。如下:

select * from user where id = 1 for update; 读写锁,排他锁
select * from user where id = 1 lock in share mode; 读锁,共享

写操作

写操作的时候,又分为删除,修改,添加三种方式。

  • delete删除的时候,在数据库中底层的逻辑其实是将这个数据给隐式删除,只要当前查询不出来就可以了。所以这时候加的就是一个X锁。
  • update修改的时候,又分为两种情况,一种是修改原数据记录,这时候加上一个X锁就行了。另一种是可能把这个原数据id之类的涉及到存储位置变动的操作,那先定位到数据加上X锁,然后将数据和锁都删除。再插入条新数据就可以了
  • insert插入操作的时候,并不会显式的加锁,会有一种叫做隐式锁的机制来处理,我们后面细说。

表锁

上面我们说的这些锁操作,默认都是加在记录上的。其实我们也可以直接给表加上S锁或者X锁。

这时候问题就来了,这里的S锁和X锁的兼容性是没变的,依旧是 只有S锁和S锁可以相互兼容,S锁与X锁,还有X锁与X锁之间都是互斥的。

  • 当表中某些数据存在S锁的时候,是不能加X锁的。
  • 表中某些数据存在X锁,也是不能加S锁和X锁的。

但是,加表锁的时候,难道要扒拉一遍表中所有数据,看看都有没有加锁吗? 不可能的,这辈子都不可能的。

所以这里还有一个表级意向锁的概念,每当有事务给某个记录加了锁,就要在表上加上一个意向锁。如果表记录中有S锁,那么表上肯定就有IS表级意向锁;如果表记录中有X锁,那么表上肯定就有IX表级意向锁。

所以当我们想要再表上加锁的时候,要看我们加的锁是不是和记录中的锁互斥,互斥的话就是不能加的。
在这里插入图片描述
其实表的锁有些鸡肋,一般情况下是用不到的。真想使用的时候可以通过这个语句手动添加:
LOCK TABLES t READ : InnoDB 存储引擎会对表 t 加表级别的 S锁 。
LOCK TABLES t WRITE : InnoDB 存储引擎会对表 t 加表级别的 X锁 。

行锁

上面我们已经了解了锁的大部分概念,但是在真正的记录锁/行锁使用中,还是有其他问题要解决的。

在这里插入图片描述
比如现在有这样一批数据,如上图。

想要在8这条记录加上一个锁,无论是加X锁或者S锁都是可以的。加上之后防止其他事务来修改数据。

但是我们已经知道隔离级别有个幻读的问题,为了解决这个问题,mysql还有一个间隙锁的概念。就是在记录与记录之间加一个间隙锁。防止当前事务处理期间,在这些数据中插入新的记录。注意,间隙锁只会加在记录的前面。 也就是说,想要给8这个数据加间隙锁的时候,默认是加在记录3和记录8之间。这时候就有个问题了,第一条还可以,那最后一条怎么加间隙锁? 也是有办法的。

还记得之前讲页面数据结构的时候,记录是一个链表,链表的尾部会固定的指向数据页固定的一个最大记录,这个最大记录是假的。数据页出现的时候就存在,就是用来定位记录链表的最后一条数据。那么往最后一条记录加间隙锁的时候,就可以在那条(伪)最大记录上加就可以了。

如果锁住某条记录,并且顺便把间隙锁加上的这种操作,官方称为next-key锁

当其他事务想要在这些记录中间插入数据的时候,会先判断该位置是否有间隙锁。如果存在间隙锁的话,就获取锁失败,陷入等待状态。一直等到前面的事务释放了这个锁,会唤醒等待的事务线程来竞争锁。
在这里插入图片描述
action:这里的锁是如何竞争,前一个事务如何唤醒后面的事务,没有找到这方面相关资料。

隐式锁

上面提过这个概念,就是在新插入一条记录的时候,并不会主动加上锁。还记得我们在MVCC机制中介绍的时候,每条记录都有一个最后修改事务id的隐藏列吗?

如果后来的事务想要给这条新记录加锁的时候,会先查看一下这个记录的最后修改id是否还在活跃中。如果还在活跃,证明当前还未提交。就主动给当前活跃的这个事务加锁,再给自己加一个等待锁。这就是一种隐式锁的概念。

死锁

如果有这样两个事务A、B,他们分别都要执行不相关的两批数据,1、2和a。但是执行执行顺序不同。A先在1、2两条记录加了锁,B先在a记录加了锁。等双方想去获取剩余记录锁的时候,发现已经被占用了,于是都在等待对方释放锁。这就造成了死锁的问题。

InnoDB会检测这种循环等待释放的死锁问题,如果检测到两个事务因为这种问题陷入了死锁,超过一定时间,InnoDB引擎会把修改记录比较少的那个事务先给回滚了,避免一直死锁。这是一种相对来说比较优的解决方式。

这说的是引擎查询导致的死锁问题,还有一种是我们分布式数据加悲观锁处理导致的死锁问题,可以改为乐观锁+版本号的操作,这里就先不展开讲了。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

leetocde662. 二叉树最大宽度,面试必刷题,思路清晰,分点解析,附代码详解带你完全弄懂

leetocde662. 二叉树最大宽度 做此题之前可以先做一下二叉树的层序遍历。具体题目如下: leetcode102二叉树的层序遍历 我也写过题解,可以先看看学习一下,如果会做层序遍历了,那么这题相对来说会简单很多。 具体题目 给你一棵…

Vue3+Element Plus 实现table表格中input的验证

实现效果 html部分 <template><div class"table"><el-form ref"tableFormRef" :model"form"><el-table :data"form.detailList"><el-table-column type"selection" width"55" align&…

Wonder3D 论文学习

论文链接&#xff1a;https://arxiv.org/abs/2310.15008 代码链接&#xff1a;https://github.com/xxlong0/Wonder3D 解决了什么问题&#xff1f; 随着扩散模型的提出&#xff0c;3D 生成领域取得了长足进步。从单张图片重建出 3D 几何是计算机图形学和 3D 视觉的基础任务&am…

【限免】16PAM、16PSK、16QAM、16CQAM星座图及误码率【附MATLAB代码】

​微信公众号&#xff1a;智能电磁频谱算法 QQ交流群&#xff1a;949444104 主要内容 MATLAB代码 % Parameters M 16; N 4; % Number of circles for CQAM SNR_dB 0:2:25; % Extended SNR range to reach higher values num_symbols 1e5; % Total number of symbols for s…

Linux学习笔记 --- 环境配置

在成功装载Ubuntu系统后我们需要设置其与windows系统的共享文件夹&#xff0c;按照以下步骤操作 设置完共享文件夹后在终端执行以下命令查看是否成功设置 此时下方出现设置的共享文件夹名称则为成功设置 如果未显示可以尝试进行重新安装VMware tools&#xff0c;步骤如下&…

git等常用工具以及cmake

一、将git中的代码克隆进电脑以及常用工具介绍 1.安装git 首先需要安装git sudo apt install git 注意一定要加--recursive&#xff0c;因为文件中有很多“引用文件“&#xff0c;即第三方文件&#xff08;库&#xff09;&#xff0c;加入该选项会将文件中包含的子模…

系统架构设计师②:操作系统

系统架构设计师②&#xff1a;操作系统 操作系统作用 ①管理系统的硬件、软件、数据资源 ②控制程序运行 ③人机之间的接口 ④应用软件与硬件之间的接口 进程管理 进程是程序在一个数据集合上运行的过程&#xff0c;它是系统进行资源分配和调度的一个独立单位。它由程序块、…

FastAPI(七十八)实战开发《在线课程学习系统》接口开发-- 评论

源码见&#xff1a;"fastapi_study_road-learning_system_online_courses: fastapi框架实战之--在线课程学习系统" 梳理下思路 1.判断是否登录 2.课程是否存在 3.如果是回复&#xff0c;查看回复是否存在 4.是否有权限 5.发起评论 首先新增pydantic模型 class Cour…

如何系统的学习C++和自动驾驶算法

给大家分享一下我的学习C和自动驾驶算法视频&#xff0c;收藏订阅都很高。打开下面的链接&#xff0c;就可以看到所有的合集了&#xff0c;订阅一下&#xff0c;下次就能找到了。 【C面试100问】第七十四问&#xff1a;STL中既然有了vector为什么还需要array STL中既然有了vec…

C#如何引用dll动态链接库文件的注释

1、dll动态库文件项目生成属性中要勾选“XML文档文件” 注意&#xff1a;XML文件的名字切勿修改。 2、添加引用时XML文件要与DLL文件在同一个目录下。 3、如果要是添加引用的时候XML不在相同目录下&#xff0c;之后又将XML文件复制到相同的目录下&#xff0c;需要删除引用&am…

VUE3学习第三篇:报错记录

1、在我整理好前端代码框架后&#xff0c;而且也启动好了对应的后台服务&#xff0c;访问页面&#xff0c;正常。 2、报错ReferenceError: defineModel is not defined 学到这里报错了 在vue网站的演练场&#xff0c;使用没问题 但是在我自己的代码里就出问题了 3、watchEffec…

企业公户验证API如何使用JAVA、Python、PHP语言进行应用

在纷繁复杂的金融与商业领域&#xff0c;确保每笔交易的安全与合规是至关重要的。而企业公户验证API&#xff0c;正是这样一位默默守护的数字卫士&#xff0c;它通过智能化的手段&#xff0c;简化了企业对公账户验证流程&#xff0c;让繁琐的审核变得快捷且可靠。 什么是企业公…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十七章 Linux中断实验

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

普元开源OBS仓颉版客户端,相较于Java实现桶创建接口平均响应时长缩小46.8%

关于作者&#xff1a;许飞锋&#xff0c;资深软件工程师&#xff0c;参与公司多个核心产品的设计与开发&#xff0c;对中间件相关技术及组件研究较多&#xff0c;对仓颉语言特性及神农框架理解较深入。 01‍ 关于OBS仓颉版客户端 1.1 组件定位 对象存储服务软件开发工具包&…

Canvas生成动画---显示一组彩色气泡

一、JS版本 <!--* Author: LYM* Date: 2024-07-26 13:51:47* LastEditors: LYM* LastEditTime: 2024-07-26 16:14:40* Description: Please set Description --> <!DOCTYPE html> <html> <head><title>canvas动态气泡</title><style&g…

Spring Boot的Web开发

目录 Spring Boot的Web开发 1.静态资源映射规则 第一种静态资源映射规则 2.enjoy模板引擎 3.springMVC 3.1请求处理 RequestMapping DeleteMapping 删除 PutMapping 修改 GetMapping 查询 PostMapping 新增 3.2参数绑定 一.支持数据类型: 3.3常用注解 一.Request…

Spark+实例解读

第一部分 Spark入门 学习教程&#xff1a;Spark 教程 | Spark 教程 Spark 集成了许多大数据工具&#xff0c;例如 Spark 可以处理任何 Hadoop 数据源&#xff0c;也能在 Hadoop 集群上执行。大数据业内有个共识认为&#xff0c;Spark 只是Hadoop MapReduce 的扩展&#xff08…

22 Python常用内置函数——枚举

enumerate() 函数用来枚举可迭代对象中的元素&#xff0c;返回可迭代的 enumerate 对象&#xff0c;其中每个元素都是包含索引和值的元组。 print(enumerate(abcd)) print(list(enumerate(abcd))) # 枚举字符串中的元素 print(list(enumerate([hello, world]))) # 枚举列表中…

【数据结构】:大厂面试经典链表OJ题目详解

反转链表 206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 思路解透 本题就是通过不停地将最先的 head 节点位置的后一位插到最前面&#xff0c;完成链表的反转 本题需要两个节点变量 cur&#xff1a;其任务就是定位到原 head 节点位置的前一位&#xff0c;然后将自己…

百日筑基第二十八天-23种设计模式-行为型总汇

百日筑基第二十八天-23种设计模式-行为型总汇 文章目录 百日筑基第二十八天-23种设计模式-行为型总汇前言模板方法模式简介模板方式的特点模板方法模式结构类图模板方式模式案例分析模板方法模式应用源码分析模板方法模式的注意事项和细节 迭代器模式迭代器模式结构类图迭代器模…