首页 > 数据库 >数据库系列:RR和RC下,快照读的区别

数据库系列:RR和RC下,快照读的区别

时间:2023-11-22 14:33:26浏览次数:37  
标签:事务 快照 隔离 RR Read 数据库 提交 RC

数据库系列:MySQL慢查询分析和性能优化
数据库系列:MySQL索引优化总结(综合版)
数据库系列:高并发下的数据字段变更
数据库系列:覆盖索引和规避回表
数据库系列:数据库高可用及无损扩容
数据库系列:使用高区分度索引列提升性能
数据库系列:前缀索引和索引长度的取舍
数据库系列:MySQL引擎MyISAM和InnoDB的比较
数据库系列:InnoDB下实现高并发控制
数据库系列:事务的4种隔离级别

1 介绍

上一篇,我们介绍了 SQL92标准中事务的四种隔离级别,并讨论了每种隔离级别下 脏读、不可重复读、幻读 问题是否可以解决:

隔离级别 脏读 不可重复读 幻读
读未提交:Read Uncommitted ×
读已提交:Read Committed × ×
可重复读:Repeatable Read × ×
串行化:Serializable × × ×

在 读已提交(Read Committed) 和 可重复读(Repeatable Read)两种隔离级别上,数据库底层采用了快照读(Snapshot Read)的模式来实现高并发机制。
那RC 和 RR这两种的隔离级别上的快照读(Snapshot Read)有什么区别呢,咱们往下探索?

2 RC 和 RR下快照读的区别

2.1 啥是快照读?

MySQL中InnoDB存储引擎的快照读(Snapshot Read)是一种读取数据的方式,它可以在事务开始时创建一个数据快照,这个快照是一致性的,即读取在事务开始时或特定时间点之前提交的数据。底层原理是MySQL使用多版本并发控制(MVCC)机制来实现快照读。在MVCC中,每个事务读取的数据都是根据事务开始时间点或快照时间点确定的。MySQL通过为每一行数据添加版本信息(如创建版本、删除版本等),来保留历史数据的多个版本。通过一种不加锁一致性读(Consistent Nonlocking Read)的方式来实现高并发的能力。

2.2 RU和Serializable为啥不采用快照读?

  • Serializable是串行化执行,每个步骤都是顺序的,一项事务执行完成才能执行另一项事务,所以没有MVCC 多版本的必要。
  • RU是读未提交,所有未完成的、未最终提交事务都可以被读取到,所以任何有变化的数据都会被读取到,即使是还没有Commit,也没有多版本的必要了。

2.3 读已提交(Read Committed)

  • 事务隔离级别的一种,简称RC
  • 解决了“脏读”问题,保证读取到的所有都是已提交事务的,并最终落库的
  • 可能存在“读幻影行”问题,同一个事务中,前后连续的select可能读到不同的结果集

2.4 可重复读(Repeated Read)

  • 事务隔离级别的一种,简称RR
  • 它不仅解决“脏读”问题,还解决了“读幻影行”的问题,同一个事务里,前后连续的select读到始终相同的结果集

2.5 不同隔离级别下快照读的区别

2.5.1 案例解析1

事务执行顺序如下:

时间序列 A事务 B事务
T1 开始事务
T2 开始事务
T3 查询xx账户余额(假设默认有500元)
★SELECT balance FROM acount WHERE customer_id=123456;
T4 xx账户存入1000元(未提交)
★UPDATE acount SET balance=balance+1000.00 WHERE customer_id=123456;
T5 查询A账户余额
T6 提交事务
★commit;
T7 查询A账户余额
  • Repeated Read 隔离级别

    • T3读到的结果肯定是500,这是B事务的第一个read
    • T5读到的结果也是500,因为A事务还没有提交
    • T7读到的结果还是500,因为A事务是在时间T5之后提交的,T7读到和T5一样的结果(重复读)
  • Read Committed 隔离级别

    • T3读到的结果肯定是500,这是B事务的第一个read
    • T5读到的结果也是500,因为A事务还没有提交
    • T7读到的结果还是1500,因为A事务已经提交,T7读到Commit后的结果(读已提交)

2.5.2 案例解析2

事务执行顺序如下:

时间序列 A事务 B事务
T1 开始事务(假设默认有500元)
T2 开始事务
T3 xx账户存入1000元(未提交)
★UPDATE acount SET balance=balance+1000.00 WHERE customer_id=123456;
T4 提交事务
★commit;
T5 查询A账户余额
★SELECT balance FROM acount WHERE customer_id=123456;
  • Repeated Read 隔离级别:唯一的一次读是在A事务提交之后的读,所以结果肯定是1500
  • Read Committed 隔离级别:读取已提交之后的数据,所以毫无疑问依然是1500

2.6 区别总结

首先,事务总能够读取到自己写入(update /insert /delete)的行记录。而其他事务的提交,则分情况。
RC模式,快照读总是能读到最新的行数据快照,当然,必须是已提交事务写入的。
RR模式,某个事务首次read记录的时间为T1,之后的操作不会读取到T1时间之后已提交事务写入的记录,以保证连续相同的read读到相同的结果集。
简单点说:

  • RR下,事务在第一个Read操作时,会建立Read View,并贯穿整个事务的过程,保证了可重复读的效果。
  • RC下,事务在每次Read操作时,都会建立Read View,以保证获取到的都是数据库中最新的被Commit的值。

标签:事务,快照,隔离,RR,Read,数据库,提交,RC
From: https://www.cnblogs.com/wzh2010/p/15886905.html

相关文章

  • VS2022下nuget包同步失败,提示: PackageSourceMapping 已启用,未考虑以下源: **
    随着Net8的发布,顺带VS2022升级到17.8后,发现nuget还原恢复多了一些配置: 有问题的时候,会提示未找到映射源,此时编译会报错,如下示例: 严重性代码说明项目文件行禁止显示状态错误NU1100无法解析net7.0-android33.0的“HarfBuzzSharp.NativeAssets.Linux(>=2.8.2.3)”......
  • SRC漏洞挖掘的一点小引导
    SRC漏洞挖掘第一阶段:具有python等编程基础菜鸟教程学习语法:https://www.runoob.com/python/python-tutorial.htmlPython编程基础:https://www.icourse163.org/course/NKU-1205696807第二阶段:掌握常见漏洞原理与利用技巧关于常见漏洞原理与利用技巧学习可以根据以下三个阶段......
  • 【略读论文|时序知识图谱补全】Hierarchical Self-Atention Embedding for Temporal K
    会议:WWW,时间:2023,学校:东北大学计算机与通信工程学院摘要:目前TKGC模型存在的问题:只考虑实体或关系的结构信息,而忽略了整个TKG的结构信息。此外,它们中的大多数通常将时间戳视为一般特征,不能利用时间戳的潜在时间序列信息。本文的方法:一种基于自注意机制和历时嵌入技术的分层自注意......
  • Codeforces Round 905 (Div. 2)
    \(A.Chemistry\)https://codeforces.com/contest/1888/submission/233505834\(B.Raspberries\)https://codeforces.com/contest/1888/submission/233506474\(C.YouAreSoBeautiful\)题意:给定一个长\(n\)的序列\(a\)。对于区间\([l,r]\),如果\(a\)没有其它子序列(......
  • 教你如何使用PyTorch解决多分类问题
    本文分享自华为云社区《使用PyTorch解决多分类问题:构建、训练和评估深度学习模型》,作者:小馒头学Python。引言当处理多分类问题时,PyTorch是一种非常有用的深度学习框架。在这篇博客中,我们将讨论如何使用PyTorch来解决多分类问题。我们将介绍多分类问题的基本概念,构建一个简单的......
  • 队列和循环队列(ArrayQueueAndCircleQueue)
    队列数组队列1.初始化队列privateintmaxsize;//最大长度privateintfront;//指向队首的前一个位置privateintrear;//指向队尾privateint[]arr;publicArrayQueue(intmaxsize){this.maxsize=maxsize;arr=newint[maxsize];......
  • mysql无法登陆,报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' (
    问题描述在使用命令行登录MySQL时出现了下述问题: 出错原因usingpassword:NO:表示输入没有输入密码就尝试登陆了usingpassword:YES:表示输入了密码,但密码错误 解决方案:修改密码1.修改mysql配置文件my.cnf。在 [mysqld]增加skip-grant-tables 无密码进入mys......
  • UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token '??=' 报错处理
    在用vite创建react的时候install完成后输入pnpmrundev突然蹦出UnhandledPromiseRejectionWarning:SyntaxError:Unexpectedtoken'??='一脸闷逼,百度了一下。哦吼,逻辑空赋值(??=)是ES2021的语法,nodev15.0.0以上才支持逻辑空赋值(??=)的语法。之前为了兼容旧代码使用的n......
  • 稀疏数组(sparseArray)
    稀疏数组1.二维数组转成稀疏数组//将二维数组转成稀疏数组//1.得到非零个数sumintsum=0;for(inti=0;i<chessArray.length;i++){for(intj=0;j<chessArray.length;j++){if(chessArray[i]......
  • Terraform专题精讲——为什么使用 Terraform
    为什么使用Terraform一、什么是基础设施即代码?https://aws.amazon.com/cn/what-is/iac/ 亚马逊AWS最早提出了基础设施即代码(InfrastructureasCode,简称IaC)的概念。基础设施即代码(IaC)是指使用代码而不是手动流程和设置来配置和支持您的计算基础设施的能力。任何应用程序环......