MySQL八股学习记录4事务的实现from小林coding

news/2024/11/7 22:37:07/

MySQL八股学习记录4事务的实现from小林coding

  • 事务的概念与特性
  • 并行事务引发的问题
    • 脏读
    • 不可重复读
    • 幻读
  • MySQL的应对策略
    • InnoDB引擎可重复读详解
      • ReadView在MVCC中的工作方式
      • 两种隔离级别通过MVCC实现
      • 幻读被完全解决了吗

事务的概念与特性

概念:一个操作要么执行成功,要么回滚到执行前的状态
特性:ACID
原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成
一致性(Consistency):事务操作前和操作后,满足用户层的约束性
隔离性(Isolation):数据库允许多个事务同时对数据进行读写,隔离性可以保证多个事务同时读写的数据一致性
持久性(Durability):事务结束后,对事务的修改就是永久的,即使系统故障也不会丢失
事务四大特性的保证
持久性:redo log(重做日志)
原子性:undo log(回滚日志)
隔离性:MVCC(多版本并发控制)或锁机制实现的
一致性:通过持久 + 原子性 + 隔离性 保证

并行事务引发的问题

脏读

一个事务读到另一个未提交事务修改后的数据称为脏读
上图
脏读
场景:若A发生了回滚,那么B得到的数据是错误的数据

不可重复读

一个事务内对同一个数据的两次读取,读取到的数据不相同,称为不可重复读
不可重复读
场景:若A读取了数据,并且B提交了事务,那么A再次读取的数据就会与A上次读到的数据不一样

幻读

一个事务内多次查询Count,若两次的记录数量并不相同,那么发生了幻读现象
幻读
场景:事务B查询数据,之后事务A插入一条数据,并且提交,这个时候B再去读数据就会发现两次读取到的条数不一致,就像发生了幻觉一样

MySQL的应对策略

由于上述问题的存在,MySQL提出了四种隔离级别分别是

  • 读未提交:一个事务未提交,他的结果就能被其他事务看到
  • 读已提交:一个事务提交后,结果才能被其他事务看到
  • 可重复读:一个事务过程中看到的数据,与这个事务启动时看到的数据是一样的,InnoDB的默认隔离级别
  • 串行化:对记录加上读写锁,多个事务读写必串行
    在这里插入图片描述

InnoDB引擎可重复读详解

InnoDB引擎很大程度上的避免了幻读现象但并未完全避免方案有两种

  • 针对快照读(普通select),MVCC方式解决幻读:
  • 针对当前读(除了普通select都是这个读),next-key lock(记录锁+间隔锁)方式解决幻读

对于读提交和可重复读隔离级别的事务来说,通过Read View实现,读提交与可重复读的快照时间不同,可重复读是在每个事务之前生成一个快照,读提交是在每个语句前进行快照操作

ReadView在MVCC中的工作方式

ReadView有关的四个字段
聚簇记录中还有两个隐藏列

在这里插入图片描述
其中

  • trx_id:改动该数据的事务ID
  • roll_pointer:改变记录后,旧版本的记录将会被写入到undo日志中,通过该指针能找到旧版本的记录
    创建Read View后,记录中的trx_id可以划分成三种情况
    在这里插入图片描述
    一个事务访问记录时,自己更新的记录总是可见,其余情况下有
  • 如果记录的trx_id小于ReadView中的min_trx_id,那么表示该事务在创建ReadView之前生成,那么对当前事务可见
  • 如果记录的trx_id大于等于max_trx_id,那么这个版本的记录在创建ReadView后才生成,那么对该版本记录不可见,通过undolog去查找
  • 如果trx_id在ReadView的min_trx和max_trx之间,需要判断trx_id是否在m_ids列表中,若在,那么该版本的事务依然活跃,那么不可见,若不在,则已被提交,该版本的记录对当前事务可见

两种隔离级别通过MVCC实现

  • 可重复读是事务开始时就快照,整个事务期间都使用这个快照
  • 读已提交则是每次查询数据前生成新的快照

幻读被完全解决了吗

并没有,一种场景如下,事务A先查询一个数据,然后事务B插入一个数据,之后A再对该数据更新(虽然这样的操作很违和),这样之后A就能读B插入的数据,正因为这种特殊情况的存在,所以并不能认为MVCC解决了幻读


http://www.ppmy.cn/news/921524.html

相关文章

数据结构day3(2023.7.17)

一、Xmind整理: 二、课上练习: 练习1:时间复杂度 时间复杂度:只保留最高阶f(n)3*n^2n^2100nT(n)O(3*n^3n^2100n)O(3*n^3)O(n^3)1>O(1):常数阶int ta; 1ab; 1at; 1f(n)3T(n)O(3)O(3*n^0)O(n^0)O(1)2>O(n): 线性阶for…

IPAD USB 充电程序

Ai Charger 华硕的Ai Charger软件可以用在任意Windows系统的台式电脑、笔记本、上网本… 软件的原理官方没有解释过,我猜测应该是通过修改windows系统注册表,提高USB口的供电电流。除了通用性好(可用于任何windows系统电脑)之外&a…

iPad充电器不能为iPhone充电吗?

补充:苹果官网明确,ipad充电器可以给iphone充电,但是iphone充电器则没有注明可用ipad 流言: 最近流传着这样一条微博:“请不要用iPad的充电器为iPhone充电,虽然看起来他们长的一样,两者的充电电…

iPad 4.2.1 非完美越狱

iPad 4.2.1 非完美越狱 新入手iPad 64G Wifi版,主要是想拿来看看文献,可惜EndNote没有iPad版的,App Store只找到Papers v1.9支持iPad,可惜还要15刀,再加上QuickOffice和iFiles这些文本编辑和管理软件差不多要200块&a…

iPhone/iPad的正确充电方法,有实验证明!

[交流] iPhone/iPad的正确充电方法,有实验证明! iPad, iPhone, 电池, 正确充电方法, 实验证明 由于工作性质,我属于每天不睡觉时间基本不离开电脑的。最近折腾iPad有点狠,经常连到电脑上传东西。于是就在想一个问题。iPad长时…

Python学习(八)

#altshiltctrl鼠标选中就可以同时修改 list1 [1,2,3,4,5,6] tuple1 (1,2,3,4,5,6) str "abcdef" set {1,2,3,4,5} dict {"key1":1,"key2":2,"key3":3,"key4":4} #max最大元素 print(f"列表 最大的元素是{max(lis…

Ubuntu18.04 安装vscode 配置C#编译器

环境: ubuntu 18.04 依赖库: SDK .net-7 安装对象: vscode 在终端: ./dotnet-install.sh --channel 7.0 遇见如下提示: dotnet:未找到命令 如下操作: 下载–解压–安装 wget https://pa…

铁通用户,宽带测速很快,可是上网很慢的解决办法

最近上网很慢,尤其是想要csdn上写个日志,半天打不开。 可是我是17mb的带宽,用各种测速软件测试也确实是很快的速度。可就是网页打的很慢。 还用说,就是铁通公司慢的dns服务器,跟个什么似得,懒得骂了。 解决…