MVCC 是否彻底解决了事物的隔离性 ?

目录

1. 什么是 MVCC

2. MVCC 是否彻底解决了事物的隔离性

3. MySQL 中如何实现共享锁和排他锁

4. MySQL 中如何实现悲观锁和乐观锁


1. 什么是 MVCC

        MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种多版本并发控制机制,它通过给每一个操作加上一个版本号,来解决它的隔离性问题!(主要是用来解决幻读问题

        它使用了快照读的方式,将历史版本的结果集保存到缓存中(ReadView),那么后续需要查询结果集的时候,就不会进行实时的查询(当前读),而是从历史版本中找到与当前查询操作所对应的版本号匹配的结果集。(版本号是全局共享的)

        MVCC 虽然主要用来解决幻读问题的,它也是可以解决不可重复读问题的,并且 MVCC 是 MySQL 内置的一个机制,先来看看 MVCC 是如何解决不可重复读问题的:

数据库中原数据:

客户端 1 执行如下操作:

// 1.开启事物 A  [版本 1]
begin; 

// 2.查询 user 表中 id 为 3 的用户身份信息 [版本 1]
select * from user where id = 3; 

// 3.等事物 B 执行修改操作后,再次查询 id 为 3 的用户 [取缓存中的版本 1]
select * from user where id = 3;

客户端 2 执行如下操作:

// 开启事物 [版本 1]
begin;

// 等事物 A 执行完第一次查询操作时,将 id 为 3 的用户名改为王老五 [版本 2]
update user set name = '王老五' where id= 3;

// 提交事物
commit;

// 此时可以再开一个客户端 3,验证一下数据库中是否已经是最新数据

 经过上述两步操作之后,可以得出以下结果 >>

  • 客户端 1:因为客户端 1 只执行了开启事务,并没有提交事物,所以客户端 1 第二次查询得到的数据行的 name 依然是 王五。
  • 客户端 3 :因为客户端 2 执行了修改操作,并提交事物,那么客户端 3 查询得到的数据行的 name 就变成了 王老五。

MVCC 的核心思想:

        MVCC 将每个事物的读和写操作进行解耦,通过保存数据的历史版本来实现并发控制。每个事物在开始的时候会创建一个读视图(ReadView),用于确定在事物开始时可见的数据版本。在 MVCC 中,当一个事物执行写操作时,会生成一个新的数据版本并将旧版本的数据保存在回滚日志(Undo Log)中。这样其他事物在读取数据时,仍然可以访问到旧版本的数据,从而避免了幻读问题和不可重复读问题。

(历史版本的数据就类似于对之前查询出来的结果集拍张照,在当前事物还没执行完,还需要查询时,直接从缓存中拿那个版本的照片)

2. MVCC 是否彻底解决了事物的隔离性

        在面试中如果被问到这个问题了,那么回答没有彻底解决。虽然 RR 隔离级别中通过 MVCC 解决大部分幻读问题,但是依然存在幻读问题。

请看示例,原数据:

 客户端 1 执行如下操作:

// 事物 A
begin;

select * from user where id > 0 and id < 9;

// 等待事物 B 执行完新增操作后,使用下面两种方式进行查询
select * from user where id > 0 and id < 9; [快照读]

select * from user where id > 0 and id < 9 for update; [当前读]

客户端 2 执行如下操作:

begin;

// 事物 B 执行新增操作
insert into user(id,name,age,address) values(4,'老六',66,'广州');

commit;

最终执行结果:

  • 事物 A 使用快照读(读缓存)的方式,查询结果集仍然是 3 条,(MVCC机制保护)
  • 事物 A 使用当前读(实时读)的方式,查询结果集变成了 4 条。(存在幻读问题)

【解决方案】既然 MVCC 也不能解决幻读问题,那么该怎么解决幻读问题 ??

  • 方案一:加锁 + RR隔离级别
  • 方案二:使用串行化隔离级别

MySQL 中如何加锁,使用 for update (既是当前读,也是加锁),示例:

select * from user where id > 0 and id < 9 for update; // 排他锁(写锁)

        当事物 A 在执行时,进行锁表操作,那么事物 B 开启事物后,想要执行新增操作,但是事物 A 已经执行锁表操作了,所以事物 B 尝试获取锁,发现获取不到,一段时间后就放弃了,所以显示获取锁超时的错误(默认超时时间为 50s)。

3. MySQL 中如何实现共享锁和排他锁

共享锁也称为读锁,它允许多个事物同时获取同一数据的共享锁,用于读数据。

语法:  select... lock in share mode

select * from user wehre id = 1 lock in share mode;

排他锁也称为写锁,它只允许一个事物获取排他锁,用于修改数据。

语法: select .... for update

select * from user where id = 1 for update;

4. MySQL 中如何实现悲观锁和乐观锁

1. 悲观锁

悲观锁就是通过加上 for update 进行锁表的操作实现的

2. 乐观锁

MySQL 没有内置乐观锁的实现,需要在业务代码中通过手动指定版本号来实现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue项目使用qrcodejs2遇到Cannot read property ‘appendChild‘ of null

这个问题是节点还没创建渲染完就读取节点&#xff0c;这个时候应该先让节点渲染完成在生成&#xff0c;解决方法有以下两种 1、使用$nextTick&#xff08;&#xff09;方法进行&#xff0c;这个方法是用来在节点创建渲染完成后进行的操作 that.$nextTick(() > {let qrcode …

Java基础知识小结(内部类、BigInteger、枚举、接口、重写重载和序列化)

一、Java内部类 1、内部类 在Java中&#xff0c;也可以嵌套类&#xff08;类中的类&#xff09;。嵌套类的目的是将属于同一类的类分组&#xff0c;这使代码更具可读性和可维护性。 要访问内部类&#xff0c;请创建外部类的对象&#xff0c;然后创建内部类的对象&#xff1a;…

SpringBoot中优雅的实现隐私数据脱敏(提供Gitee源码)

前言&#xff1a;在实际项目开发中&#xff0c;可能会对一些用户的隐私信息进行脱敏操作&#xff0c;传统的方式很多都是用replace方法进行手动替换&#xff0c;这样会由很多冗余的代码并且后续也不好维护&#xff0c;本期就讲解一下如何在SpringBoot中优雅的通过序列化的方式去…

【框架类】—MVVM框架

一、MVVM框架有哪些 Vue.jsReact.jsAngular.js 二、对MVVM的认识 1. MVC是什么 全称 Model View Controller, 它采用模型(Model)-视图(View)-控制器(controller)的方法把业务逻辑、数据与界面显示分离 2. MVVM的定义 MVVM是一种软件架构模式&#xff0c;它代表了模型 --视…

深入理解JVM——垃圾回收与内存分配机制详细讲解

所谓垃圾回收&#xff0c;也就是要回收已经“死了”的对象。 那我们如何判断哪些对象“存活”&#xff0c;哪些已经“死去”呢&#xff1f; 一、判断对象已死 1、引用计数算法 给对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器就加一&…

探索无限创造力的星辰大道,画出想象的浩瀚宇宙!-turtle

介绍 视频教程地址在此&#xff1a;https://www.bilibili.com/video/BV1Pm4y1H7Tb/ 大家好&#xff0c;欢迎来到本视频&#xff01;今天&#xff0c;我们将一同探索Python编程世界中的一个有趣而创意的库——Turtle库。无需专业绘画技能&#xff0c;你就可以轻松地用代码绘制…

人工智能在网络安全中的作用:当前的局限性和未来的可能性

人工智能 (AI) 激发了网络安全行业的想象力&#xff0c;有可能彻底改变安全和 IT 团队处理网络危机、漏洞和勒索软件攻击的方式。 然而&#xff0c;对人工智能的能力和局限性的现实理解至关重要&#xff0c;并且存在许多挑战阻碍人工智能对网络安全产生直接的变革性影响。 在…

概述、搭建Redis服务器、部署LNP+Redis、创建Redis集群、连接集群、集群工作原理

Top NSD DBA DAY09 案例1&#xff1a;搭建redis服务器案例2&#xff1a;常用命令限案例3&#xff1a;部署LNPRedis案例4&#xff1a;创建redis集群 1 案例1&#xff1a;搭建redis服务器 1.1 具体要求如下 在主机redis64运行redis服务修改服务运行参数 ip 地址192.168.88.6…

在 ubuntu 18.04 上使用源码升级 OpenSSH_7.6p1到 OpenSSH_9.3p1

1、检查系统已安装的当前 SSH 版本 使用命令 ssh -V 查看当前 ssh 版本&#xff0c;输出如下&#xff1a; OpenSSH_7.6p1 Ubuntu-4ubuntu0.7, OpenSSL 1.0.2n 7 Dec 20172、安装依赖&#xff0c;依次执行以下命令 sudo apt update sudo apt install build-essential zlib1g…

[论文笔记]Glancing Transformer for Non-Autoregressive Neural Machine Translation

引言 这是论文Glancing Transformer for Non-Autoregressive Neural Machine Translation的笔记。 传统的非自回归文本生成速度较慢,因为需要给定之前的token来预测下一个token。但自回归模型虽然效率高,但性能没那么好。 这篇论文提出了Glancing Transformer,可以只需要一…

6.RocketMQ之索引文件ConsumeQueue

本文着重分析为consumequeue/topic/queueId目录下的索引文件。 1.ConsumeQueueStore public class ConsumeQueueStore {protected final ConcurrentMap<String>, ConcurrentMap<Integer>, ConsumeQueueInterface>> consumeQueueTable;public boolean load(…

Selenium 测试用例编写

编写Selenium测试用例就是模拟用户在浏览器上的一系列操作&#xff0c;通过脚本来完成自动化测试。 编写测试用例的优势&#xff1a; 开源&#xff0c;免费。 支持多种浏览器 IE&#xff0c;Firefox&#xff0c;Chrome&#xff0c;Safari。 支持多平台 Windows&#xff0c;Li…

Xxl-job安装部署以及SpringBoot集成Xxl-job使用

1、安装Xxl-job&#xff1a; 可以使用docker拉取镜像部署和源码编译两种方式&#xff0c;这里选择源码编译安装。 代码拉取地址&#xff1a; https://github.com/xuxueli/xxl-job/tree/2.1.2 官方开发文档&#xff1a; https://www.xuxueli.com/xxl-job/#%E3%80%8A%E5%88%…

Android5:活动生命周期

创建项目Stopwatch activity_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayoutxmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_w…

ROS-PyQt小案例

前言&#xff1a;目前还在学习ROS无人机框架中&#xff0c;&#xff0c;&#xff0c; 更多更新文章详见我的个人博客主页【前往】 ROS与PyQt5结合的小demo&#xff0c;用于学习如何设计一个界面&#xff0c;并与ROS中的Service和Topic结合&#xff0c;从而控制多个小乌龟的运动…

设计HTML5表单

HTML5基于Web Forms 2.0标准对HTML4表单进行全面升级&#xff0c;在保持简便、易用的基础上&#xff0c;新增了很多控件和属性&#xff0c;从而减轻了开发人员的负担。表单为访问者提供了与网站进行互动的途径&#xff0c;完整的表单一般由控件和脚本两部分组成。 1、认识HTML…

ansible的playbook剧本

playbook剧本 PlayBook1.playbooks 本身由以下各部分组成2.示例&#xff1a;3.运行playbook补充参数&#xff1a; 4.定义、引用变量5.指定远程主机sudo切换用户6.when条件判断7.迭代8.Templates 模块1.先准备一个以 .j2 为后缀的 template 模板文件&#xff0c;设置引用的变量2…

记录--webpack和vite原理

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 每次用vite创建项目秒建好&#xff0c;前几天用vue-cli创建了一个项目&#xff0c;足足等了我一分钟&#xff0c;那为什么用 vite 比 webpack 要快呢&#xff0c;这篇文章带你梳理清楚它们的原理…

Linux命令200例:clock的具体应用,设置系统的时钟时间、硬件时钟和定时器等相关信息

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

Atlas 元数据管理

Atlas 元数据管理 1.Atlas入门 1.1概述 元数据原理和治理功能&#xff0c;用以构建数据资产的目录。对这个资产进行分类和管理&#xff0c;形成数据字典。 提供围绕数据资产的协作功能。 表和表之间的血缘依赖 字段和字段之间的血缘依赖 1.2架构图 导入和导出&#xff1…