MySQL事务隔离级别、InnoDB使用MVCC+各种锁实现了RC和RR事务隔离级别、具体案例

news2024/12/28 20:11:20

事务隔离级别

  • 脏读:一个事务读取到另一个未提交事务的更改。
  • 不可重复读:一个事务在两次读取同一数据时,发现数据被另一个已提交事务修改了。
  • 幻读:一个事务在读取过程中,因其他事务的插入而导致返回的行数不一致,查询到了奇怪的结果

SQL标准定义了如下四个隔离级别,注意是SQL标准,不是MYSQL标准:

  • READ-UNCOMMITTED(读取 未提交) :最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。几乎没人用,太不安全了。
  • READ-COMMITTED(RC,读取 已提交) :允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。经常用,可以确保并发的性能。
  • REPEATABLE-READ(RR,可重复读) :在事务开始(start TRANSACTION,关闭自动提交)和结束之间(commit,rollback之前),对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。也经常被用,可以确保安全。
    虽然标准SQL隔离级别定义是说RR下幻读仍然可能发生,但是在MYSQL的InnoDB下实现的RR隔离级别是解决了幻读问题的发生的,先有个印象,我一开始看也非常懵逼。
  • SERIALIZABLE(可串行化) :最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。几乎没人用,事务并发性能太差了。
隔离级别脏读不可重复读幻读
READ-UNCOMMITTED,读未提交
READ-COMMITTED,读已提交×
REPEATABLE-READ,可重复读××
SERIALIZABLE,可串行化×××

InnoDB使用MVCC+各种锁实现了RC和RR事务隔离级别

重点当然是讲RR的实现,因为他是MySQL默认存储引擎InnoDB的默认隔离级别。下面先说明实现存在的问题,再说解决方法。

下面无特别说明都用RR事务隔离级别做例子

一致性非锁定读

对于 一致性非锁定读(Consistent Nonlocking Reads)open in new window的实现,通常做法是加一个版本号或者时间戳字段,在更新数据的同时版本号 + 1 或者更新时间戳。查询时,将当前可见的版本号与对应记录的版本号进行比对,如果记录的版本小于可见版本,则表示该记录可见。

在InnoDB引擎中,多版本控制(multi versioning)就是对上面描述的非锁定读的实现。
如果读取的行正被其他事务执行 DELETEUPDATE 操作,这时读取操作不会去等待行上锁的释放。相反地,InnoDB 存储引擎会去读取行的一个快照数据,对于这种读取历史数据的方式,我们叫它快照读 (snapshot read)。

Repeatable ReadRead Committed 两个隔离级别下,如果是执行普通的 select 语句(不包括 select ... lock in share mode ,select ... for update)则会使用 一致性非锁定读(MVCC,多版本并发控制 (Multi-Version Concurrency Control))。并且在 Repeatable Read 下 MVCC 实现了可重复读和防止部分幻读


一致性非锁定读 代码举例
①对两个事务分别commit先,确保都提交了之前的工作。
在这里插入图片描述
②事务2虽然update修改了数据,但是可以发现事务1读取的是之前的快照
在这里插入图片描述
③先让事务2commit提交,可以发现事务1读取的还不是事务2修改的值
在这里插入图片描述
④等到事务1也commit了,下一次开启事务,查到的才是事务2修改的值
在这里插入图片描述


锁定读

如果执行的是下列三类语句,就是锁定读(Locking Reads)

  • select ... lock in share mode
  • select ... for update
  • insertupdatedelete操作

在锁定读下,读取的是数据的最新版本,这种读也被称为 当前读(current read)。锁定读 会对读取到的记录加锁:

  • select ... lock in share mode:对记录加 S 锁,其它事务也可以加S锁,如果加 x 锁则会被阻塞
  • select ... for updateinsertupdatedelete:对记录加 X 锁,且其它事务不能加任何锁
    在一致性非锁定读下,即使读取的记录已被其它事务加上 X 锁,这时记录也是可以被读取的,即读取的快照数据。上面举过例子了,在RR可重复读下,MVCC可以防止一部分情况的幻读,这一部分幻读是指在一致性非锁定读的情况下,它会根据Read View去判断数据是否可见,也就是读到的是历史数据,读的是快照。但是MVCC无法防止在当前读的情况所产生的幻读现象,当前读读取的都是最新数据。

如果单靠MVCC,在当前读的情况下,这时如果两次查询中间有其它事务插入数据,就会产生幻读。所以,InnoDB 在实现Repeatable Read时,如果执行的是当前读select 查询(说明执行了lock in share mode or for update),则会对读取的记录使用 Next-key Lock 来防止其它事务在间隙间插入数据。
Next-key Lock :(行锁record lock + 间隙锁gap lock,行锁只能锁住已经存在的行,为了避免插入新行,需要依赖间隙锁)

  • 如果数据存在,使用lock in share mode or for update就是Next-key Lock用(读 or 写)行锁
  • 如果数据不存在,使用使用lock in share mode or for update就是Next-key Lock用间隙锁,锁住区间,不让另一个事务在这个区间插入新数据。

当前读的幻读现象问题实例:
①这里使用一致性非锁定读环境下说明当前读下的幻读现象问题,因为这种情况下InnoDB只用了MVCC,没用Next-key Lockselect查询
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

问题就出在事务Aselect查询时,不应该出现幻读现象,应该在 select 查询时,带上lock in share mode or for update,则会对读取的记录使用 Next-key Lock 来防止其它事务在间隙间插入数据。

把原来的表删了,重新演示:
在这里插入图片描述
在这里插入图片描述

总结一下:

事务1的连续两个快照读中出现当前读不一定会出现幻读,得看事务1的当前读有没有覆盖到其他事务新增的数据,如果没的话,则不会出现幻读

下面是连续两个快照读中出现当前读会出现幻读,因为事务1的当前读覆盖到其他事务新增的数据。
在这里插入图片描述


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

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

相关文章

【LVS】nat模式+dr模式+防火墙标签解决轮询错误

集群:同一个业务系统,部署在多台服务器上,集群中,每一台服务器实现的功能没有差别,数据 和代码都是一样的 分布式:一个业务被拆成多个子业务,或者本身就是不同的业务,部署在多台服…

前端使用 Konva 实现可视化设计器(20)- 性能优化、UI 美化

这一章主要分享一下使用 Konva 遇到的性能优化问题,并且介绍一下 UI 美化的思路。 至少有 2 位小伙伴积极反馈,发现本示例有明显的性能问题,一是内存溢出问题,二是卡顿的问题,在这里感谢大家的提醒。 请大家动动小手&a…

【Bug记录】C2662:不能将this指针从const转换为非const

项目场景: 今天在模拟list时候,写到下面代码,出现了语法报错。 这个地方我自己的_iterator是私有的,所以提供了GetIterator接口去获取_iterator,但是不知道为什么就报出了下面的错误。 语法报错: 问题…

Element学习(表格组件、分页组件)(2)

1、表格&#xff08;table&#xff09;组件 &#xff08;1&#xff09;去element官网查看寻找想要的&#xff0c;然后复制修改就行了 &#xff08;2&#xff09;注意在组件文件中标签<template>中时注意&#xff0c;里面只能有一个根标签 &#xff08;3&#xff09;格式化…

【AI大模型】Ollama+OpenWebUI+llama3本地大模型

本地部署大模型 0.引言1.部署安装1.1部署工具1.2 概念介绍1.3 ollama安装后的基本使用1.4 大模型权重下载1.4.1 ollama在线下载1.4.2 huggingFace下载大模型权重及如何使用ollama进行调用 2.带有UI界面的使用3.参考 0.引言 &#xff08;1&#xff09;目的 本教程主要关于开源A…

数据科学和临床数据科学的发展​​​​​​​

内容来自&#xff1a;专栏《R探索临床数据科学&#xff1a;1章1节&#xff1a;数据科学与临床数据科学的发展历程&#xff1a;为何 R 备受青睐及我们专栏的独特之处》的部分 为帮助大家更出色地掌握临床统计、数据挖掘以及人工智能建模的入门知识和应用&#xff0c;由于众多同学…

Thinkphp框架漏洞(附修复方法)

ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的&#xff0c;是一个快速、兼容而且简单的轻量级国产PHP开发框架&#xff0c;诞生于2006年初&#xff0c;原名FCS&#xff0c;2007年元旦正式更名为ThinkPHP&#xff0c;遵循Apache2开源协议发布&#xff0c;从Struts…

27集28集 ESP32 AIchat cmake编译解密-《MCU嵌入式AI开发笔记》

27-28集 ESP32 AIchat cmake编译解密-《MCU嵌入式AI开发笔记》 我们这集讲解学习cmake编译流程。 为了更好的理解&#xff0c; 我们要先了解几个cmake的内部变量&#xff1a; CMAKE_SOURCE_DIR&#xff1a;整个CMake工程最顶层的CMakeLists.txt文件所在路径。 CMAKE_CURRENT…

MyBatis:Maven,Git,TortoiseGit,Gradle

1&#xff0c;Maven Maven是一个非常优秀的项目管理工具&#xff0c;采用一种“约定优于配置&#xff08;CoC&#xff09;”的策略来管理项目。使用Maven不仅可以把源代码构建成可发布的项目&#xff08;包括编译、打包、测试和分发&#xff09;&#xff0c;还可以生成报告、生…

Find My Device技术|谷歌Find My Device网络支持的功能

谷歌新的" Find My Device " 网络覆盖了全球超过数十亿台活跃设备&#xff0c;谷歌 " Find My Device " 也和苹果 " Find My " 一样&#xff0c;支持防追踪功能&#xff0c;当检测到身边有未知蓝牙防丢器跟随移动时&#xff0c;会进行警报提醒。…

【C++题解】1084. 因子求和

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1084. 因子求和 类型&#xff1a;sqrt函数入门 题目描述&#xff1a; 已知一个正整数 N&#xff08; 20≤N≤800000000 &#xff09;&#xff0c;请你编写程序求出该数的全部因子&…

论文解读(15)-UrbanGPT

加油&#xff0c;这一篇也是感受一下大语言模型的力量&#xff01; 原文&#xff1a; UrbanGPT: Spatio-Temporal Large Language Models UrbanGPT: Spatio-Temporal Large Language Models (arxiv.org) 参考&#xff1a; 时空预测与大语言模型的奇妙碰撞&#xff01;UrbanG…

网卡与Linux网络结构(上)

原本是想借着之前学习的中断进一步拓展到网卡与中断的&#xff0c;标题都写好了&#xff0c;结果低估了其中的知识面和难度。。。。。于是调整为了网卡与Linux网络结构&#xff08;上&#xff09;&#xff0c; 没错&#xff0c;仅仅只是上。。。我还是进一步低估了学习需要花费…

Zookeeper的监听机制及原理解析

系列文章目录 手把手教你安装Zookeeper 及可视化插件ZooInspector、ZKUI Zookeeper入门篇&#xff0c;了解ZK存储特点 使用Zookeeper的监听及原理解析 系列文章目录前言一、监听机制的基本概念二、Zookeeper监听原理1. 事件类型2. 监听模式与监听器类型&#xff08;1&#xff…

深入理解计算机系统 CSAPP lab:bomb

实验资源下载地址&#xff1a;csapp.cs.cmu.edu/3e/labs.html 请先查看writeup 解压后 当我们运行bomb时,发现该程序要求我们输入行,如果输入错误,程序就会返回BOOM!!!提示我们失败了. 所以我们的目标是输入正确的行.以解开bomb程序. 实验前先详细阅读bomb.c //bomb.c /*****…

6.1 模块的导入与使用:Python的秘密武器

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

Java语言程序设计基础篇_编程练习题*16.12(演示TextArea的属性)

目录 题目&#xff1a;*16.12&#xff08;演示TextArea的属性&#xff09; 习题思路&#xff1a; 代码示例 结果展示 题目&#xff1a;*16.12&#xff08;演示TextArea的属性&#xff09; 编写一个程序&#xff0c;演示文本域的属性。程序使用复选框表明文本是否换行&#xf…

Java面试题--JVM大厂篇之JVM监控与GC日志分析:优化Parallel GC性能的重要工具

目录 引言&#xff1a; 正文&#xff1a; 1. 理解GC日志的重要性 2. 启用GC日志 3. GC日志解析 4. JVM监控工具 5. 调优Parallel GC的实战技巧 痛点一&#xff1a;长时间停顿 痛点二&#xff1a;频繁的GC 痛点三&#xff1a;内存溢出 6. 实战案例分享 结束语&#…

linux进程----匿名管道和命名管道

linux进程----匿名管道和命名管道 在Linux中&#xff0c;管道是用于进程间通信的一种机制&#xff0c;可以分为两种类型&#xff1a;匿名管道&#xff08;也称为匿名fifo&#xff09;和命名管道&#xff08;也称为命名fifo或named pipe&#xff09;。 匿名管道&#xff08;An…

如何解决整数溢出问题?

1、问题解析 当以整数数据类型&#xff08;包括字节、短、长和其他类型&#xff09;存储的值过大&#xff08;大于变量可容纳的最大值&#xff09;的值时&#xff0c;将发生整数溢出&#xff08;或环 绕&#xff09;。整数的最高有效位丢失&#xff0c;而其余值则相对于最小值…