MySQL事务隔离级别及MVCC详解

MySQL的事务隔离级别及特性如下:

SERIALIZABLE(串行化):无问题,性能差;
REPEATABLE-READ(可重复读):幻读,默认隔离级别;
READ-COMMITTED(已提交读):不可重复读&幻读;
READ-UNCOMMITTED(未提交读):脏读&不可重复读&幻读。

串行化就是事务按顺序执行,没有并行,自然也就没有问题。但是性能就会比较差;
可重复读是MySQL默认的隔离级别,就是一个事务中多次读取数据,读到的数据都是一致的,不受其他事务修改的影响;
已提交读就是可以读到其他事务已经提交的数据,所以就没有了可重复读的特性;
未提交读能读到其他事务已执行但是未提交的数据,这就会产生脏读。

数据库事务隔离级别的查看和修改

-- 查看(5.7)
select @@global.tx_isolation;
select @@tx_isolation;
-- 查看(8)
select @@global.transaction_isolation;
select @@transaction_isolation;
-- 修改
set session transaction isolation level serialiable/repeatable read/……

可重复读出现幻读的情况

A事务:

start transaction;
select * from table where id = 2; //此时表中无id为2的数据

B事务:

start transaction;
insert into table(id, name) values(2, 'Wang');
commit;

A事务:

select * from table where id = 2; // 此时虽然表中已经有了,但是由于可重复读的特性,同一事务读到的数据是一致的,所以还是读不到
insert into table(id, name) values(2, 'Wang'); //报错
commit;

已提交读出现不可重复读的情况

A事务:

start transaction;
select * from table where id = 2; // 此时可以看到2的name是'Wang'

B事务:

start transaction;
update table set name = 'Yan' where id = 2;
commit;

A事务:

select * from table where id = 2; // 此时2的name变成了'Yan',这样就出现了不可重复度的问题
commit;

已提交读出现幻读的情况

A事务:

start transaction;
select * from table where id = 3; // 此时没有id为3的数据,

B事务:

start transaction;
insert into table(id, name) values(3, 'Li'); // 只插入不提交

A事务:

select * from table where id = 3; // 此时还是读不到3的数据
insert into table(id, name) values(3, 'Li'); // 此时插入数据就会有问题,因为B事务还没提交,但是已经执行了,A事务只能等待,看B事务是回滚还是提交

未提交读出现不可重复读和脏读的情况

A事务:

start transaction;
select * from table where id = 2; // 此时读到2的name为'Yan'

B事务:

start transaction;
update table set name = 'Sun' where id = 2; // 只执行不提交

A事务:

select * from table where id = 2; // 此时读到2的name为'Sun',这就已经出现了不可重复读。假设B事务现在回滚了,那么这个数据就是错的,就出现了脏读。

为提交读出现幻读的情况

A事务:

start transaction;
select * from table; // 查出全表数据为[1-'Wu'], [2-'Sun'], [3-'Li']

B事务:

delete from table where id = 3; // 删除了但是没提交

A事务:

select * from table; // 查出全表数据为[1-'Wu'], [2-'Sun'],查到3被删除了。此时B事务回滚,数据3又出来了,一会有一会没有,就出现了幻读。

MVCC

MVCC即多版本并发控制(Multi-Version Concurrent Control)。
使用可重复读和已提交读这两种隔离级别时,SELECT操作版本链的过程。

MySQL数据行中存在隐藏的3个列:row_id、trx_id、roll_pointer
row_id如果表中有主键,或者有非NULL唯一键,就不需要row_id。没有则会自动生成6个字节的row_id。
trx_id为事务id,每次开启事务都会生成,记录在数据行中。
roll_pointer则是会指向undo_log中的上一次更新的数据。更新多次就会形成版本链。

SELECT操作会生成ReadView,已提交读同一个事务中对相同数据的查询每次SELECT都会生成一个,而可重复读一个事务多个SELECT只会生成一个ReadView。
ReadView中有m_ids、min_trx_id、max_trx_id、creator_trx_id。
m_ids:生成ReadView时所有未提交的事务id。
min_trx_id:m_ids的最小值。
max_trx_id:生成ReadView时,系统应该分配给下一个事务的事务id。
creator_trx_id:生成ReadView的事务的事务id,如果只有SELECT则为0。

当SELECT生成ReadView后,从当前B+树中的数据开始查,顺着版本链从上往下查,知道找到ReadView生成前提交的最新记录,返回即可。有以下几种情况:

  1. 被访问数据的事务id小于min_trx_id,返回。
  2. 被访问数据的事务id大于等于max_trx_id,不返回。
  3. 被访问数据的事务id在m_ids中,不返回。
  4. 被访问数据的事务id在min_trx_id和max_trx_id之间,且不在m_ids中,返回。

已提交读举例

有数据[1-Wang], [2-Yan], [3-Li],插入事务id均为80。
A事务id为100更新1 = Sun,不提交。
B事务id为200更新其他表,不提交。
C事务读id为1的数据,生成ReadView,m_ids=[100, 200],min_trx_id=100, max_trx_id=201,creator_trx_id=0。
这时就该从版本链中开始寻找数据:

  1. id为1的数据目前的trx_id为100,100在m_ids中,说明那个事务在当前事务开始的时候还没执行完,不应该读出来,继续向下寻找。
  2. 此时roll_pointer指向的上次undo_log记录trx_id为80,80小于min_trx_id,说明这个事务在生成ReadView之前已经提交了,那就会读到’Wang’。

A事务提交。
B事务更新1 = Liu,不提交。
C事务读id为1的数据,再次生成ReadView,m_ids=[200],min_trx_id=200,max_trx_id=201,creator_trx_id=0。
从版本链中开始寻找数据:

  1. id为1的数据目前的trx_id为200,200在m_ids中,继续向下寻找。
  2. 下面roll_pointer指向的上一条记录trx_id为100,小于min_trx_id,所以返回了A事务修改的’Sun’。
可重复读举例

有数据[1-Wang], [2-Yan], [3-Li],插入事务id均为80。
A事务id为100更新1 = Sun,不提交。
B事务id为200更新其他表,不提交。
C事务读id为1的数据,生成ReadView,m_ids=[100, 200],min_trx_id=100, max_trx_id=201,creator_trx_id=0。
这时就该从版本链中开始寻找数据:

  1. id为1的数据目前的trx_id为100,100在m_ids中,说明那个事务在当前事务开始的时候还没执行完,不应该读出来,继续向下寻找。
  2. 此时roll_pointer指向的上次undo_log记录trx_id为80,80小于min_trx_id,说明这个事务在生成ReadView之前已经提交了,那就会读到’Wang’。

A事务提交。
B事务更新1 = Liu,不提交。
C事务读id为1的数据,由于是可重复读隔离级别,所以不再生成新的ReadView,还是用之前的,m_ids=[100, 200],min_trx_id=100, max_trx_id=201,creator_trx_id=0。
从版本链中开始寻找数据:

  1. id为1的数据目前的trx_id为200,200在m_ids中,继续向下寻找。
  2. 下面roll_pointer指向的上一条记录trx_id为100,还是在m_ids中,继续向下寻找。
  3. 再一条记录trx_id为80,小于min_trx_id,所以返回了最初的’Wang’。

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

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

相关文章

Spring单元测试+Mockito

一,背景 单元测试基本上是开发逃不过的一个工作内容,虽然往往因为过于无聊,或者过于麻烦,而停止于项目的迭代之中,不了了之了。其实不是开发们懒,而是上头要求的测试覆盖率高,但是又没有好用的…

Stable Diffusion 本地训练端口与云端训练端口冲突解决办法

方法之一,修改本地训练所用的端口 1 首先,进入脚本训练器的根目录 例如:C:\MarkDeng\lora-scripts-v1.7.3 找到gui.py 2 修改端口号 因为云端训练器也是占用28000和6006端口 那么本地改成27999和6007也是可以的 保存退出,运行启动…

深度学习 (线性回归 简洁实现)

介绍: 在线性神经网络中,线性回归是一种常见的任务,用于预测一个连续的数值输出。其目标是根据输入特征来拟合一个线性函数,使得预测值与真实值之间的误差最小化。 线性回归的数学表达式为: y w1x1 w2x2 ... wnxn b 其中&…

扩展一下BenchmarkSQL,新增支持ASE/HANA/DB2/SQLServer,可以随便用了

1 背景 提到数据库的性能,自然就避不开性能测试。有专用于测试OLTP的,也有偏重于OLAP的。本文介绍的BenchmarkSQL就属于测试OLTP中的一个,基于TPCC的。网上有很多介绍TPC*的相关测试的文章,大家可以自行脑补。而PostgreSQL自带的pgbench是属于TPCC的前一个基准测试程序,偏…

STM32/GD32——自己制定协议和解析协议数据(可能随时弃坑)

温馨提醒: 由于我最害怕的就是接触各种新协议,尤其是对各种协议和解析协议数据简直就是职业生涯的噩梦,但工作中不免和不同的协议打交道。本着要啃就啃最难的,大不了放弃的心态。所以我学习了如何自定义制定自己的协议&#xff0c…

机器学习基础知识面经(个人记录)

朴素贝叶斯 特征为理想状态下的独立同分布,作为机器学习的重要基石和工具 由贝叶斯公式推导而来 是后验概率:在B发生的条件下A发生的概率。 是似然概率: 在 发生的条件下 发生的概率。 是先验概率: 发生的概率,而不考虑 的影响。 是…

【PyQt】17.1-日历控件 不同风格的日期和时间、以及高级操作

日历控件puls版本 前言一、日历控件中不同风格的日期和时间1.1 代码1.2 注意事项格式设置m的大小写问题QTime和QDateTime的区别 1.3 运行结果 二、高级操作2.1 成倍调整2.2 下拉出日历2.3 事件函数2.4 获取设置的日期和时间 完整代码 前言 1、不同风格的日期和时间展示 2、高级…

uni-app里面如何使用图标

目录 一、导入 1.在官方(iconfont-阿里巴巴矢量图标库)选择自己想要的图标,加入购物车 2. 在点击购物车下载代码 3.解压文件夹 并更改名字 4.将文件夹(iconfont)整个放到项目中的static中 5.修改iconfont.css文件…

上位机开发 halcon坐标转轴坐标

背景 上位机开发中有一种相机叫标定相机,主要是有来给某些要进行根据CAD图点位计算时当前产品实际点位坐标时使用的一种标定测量相机。主要原理是根据两个或多个指定的标定点进行取图计算圆心坐标,再将视觉计算出的圆心坐标和取图时的轴坐标进行偏差计算。最后得到标定点轴的…

2024年3月24日暴富榜

子丑寅卯辰巳午未申酉戌亥 每天一读,《小飞生肖》运势, 让您的生活更美好! 鼠:生肖暴富榜《中暴富》 鼠:红榜衣服颜色(蓝色) 牛:生肖暴富榜《中暴富》 牛:红榜衣服颜色…

超越工具的限制!菜鸟工具箱帮你节省时间

在这个飞速发展的时代,我们越来越依赖各种工具来提高工作效率和解决问题。然而,你是否意识到,有些工具不仅仅是工具,它们还能为你带来更多的可能性和机遇?菜鸟工具箱就是这样一个超越工具本身的存在! 菜鸟工…

目标检测的指标评估

目标检测模型的评价指标主要用于衡量模型的性能,特别是它在定位和识别目标方面的准确性。以下是一些常见的评价指标: 1. 精确度 (Precision): 表示检测到的目标中,正确检测到的目标所占的比例。精确度高意味着模型产生的误报(错误…

腾讯云GPU服务器介绍_GPU实例规格价格_AI_深度学习

腾讯云GPU服务器是提供GPU算力的弹性计算服务,腾讯云GPU服务器具有超强的并行计算能力,可用于深度学习训练、科学计算、图形图像处理、视频编解码等场景,腾讯云百科txybk.com整理腾讯云GPU服务器租用价格表、GPU实例优势、GPU解决方案、GPU软…

洛谷 Cut Ribbon

思路:我们可以看出,这是一道完全背包问题,但是呢,有一点需要注意:那就是我们在装背包的时候并不能保证一定能装满背包,但是这里的背包要求是让我们装满的,所以我们需要判断这个背包装满才行&…

Linux之文件系统与软硬链接

前言 我们之前阐述的内容都是在文件打开的前提下, 但是事实上不是所有文件都是被打开的, 且大部分文件都不是被打开的(也就是文件当前并不需要被访问), 都在磁盘中进行保存. 那这些没有被(进程)打开的文件, 也是需要被管理的! 对于这部分文件核心工作之一是能够快速定位文件…

【java数据结构】基于java提供的ArrayList实现的扑克牌游戏-(附源码~)

【Java数据结构】基于java泛型实现的二维数组完成三人扑克游戏 基本框架的实现创建一副牌如何进行洗牌:每个人抓的牌放到哪里: 源码具体实现cardcardsTest 个人简介:努力学编程 每日鸡汤:stay foolish,stay hungry-史蒂芬.乔布斯斯…

pytorch图像数据集定义

文章目录 相关链接DatasetVisionDatasetDatsetFolderImageFolder torchvision.transformsPytorch LightningLightningDataModule 对于图像数据集来说,首先是在Dataset类对数据集进行定义,一般来说不定义transform,则数据为PIL Image&#xff…

Sora入门级概念、Open-Sora 1.0和现状挑战(附多个文生视频 Prompt 案例)

OpenAI Sora入门级概念 Sora模型是OpenAI 发布的人工智能模型,它主要用于生成和处理视频内容。以下是Sora模型的一些入门级概念: 视频内容生成:Sora模型能够根据文本描述生成视频内容。这意味着你可以输入一段描述性的文本,模型将基于这段文本生成相应的视频画面。场景和角…

Github 2024-03-19 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-03-19统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目9TypeScript项目2HTML项目1GDScript项目1MetaGPT: 多代理框架 创建周期:260 天开发语言:Python协议类型:MIT LicenseStar数量:35…

MongoDb数据库介绍安装使用

#安装mongodb# 第一步 下载mongoDb: 官网https://www.mongodb.com/ 第二步 进行安装配置修改Data directory 和 Log Directory 将数据目录和日志目录存放在D盘 第三步 取消install MongoDb Compass这个是安装可视化工具的意思在这里不需要 #配置环境变量加入到系统中的path环…