1.事务介绍:

  • 一般是指要做的或所做的事情。 在计算机 术语 中是指访问并可能更新数据库中各种 数据项 的一个程序 执行单元 (unit)

2.数据库事务具有ACID四大特性。

  • ACID是以下4个词的缩写:
  • 原子性(atomicity) :事务最小工作单元,要么全成功,要么全失败 。
  • 一致性(consistency): 事务开始和结束后,数据库的完整性不会被破坏 。
  • 隔离性(isolation) :不同事务之间互不影响,四种隔离级别为RU(读未提交)、RC(读已提交)、RR(可重复读)、SERIALIZABLE (串行化)。
  • 持久性(durability) :事务提交后,对数据的修改是永久性的,即使系统故障也不会丢失 。

3.隔离级别:

  • 四种隔离级别分别为:

  1)未提交读(READ UNCOMMITTED/RU) 如果一个事务读到了另一个未提交事务修改过的数据,那么这种 隔离级别 就称之为 未提交读 会产生脏读的情况

  2)   已提交读(READ COMMITTED/RC) 不可重复读:一个事务因读取到另一个事务已提交的update。导致对同一条记录读取两次以上的结果不一致。

  如果一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值,那么这种 隔离级别 就称之为 已提交读,会产生幻读的情况。

  3)可重复读(REPEATABLE READ/RR) 在一些业务场景中,一个事务只能读到另一个已经提交的事务修改过的数据,但是第一次读过某条记录后,

  即使其他事务修改了该记录的值并且提交,该事务之后再读该条记录时,读到的仍是第一次读到的值,而不是每次都读到不同的数据。那么这种 隔离级别 就称之为 可重复读,会产生幻读的情况。

  4)串行化(SERIALIZABLE) 最高的默认级别,强制事务串行执行(即一个事务一个事务执行)。效率极其低下。

  幻读:一个事务因读取到另一个事务已提交的insert数据或者delete数据。导致对同一张表读取两次以上的结果不一致。

  不可重复读: 一个事务因读取到另一个事务已提交的update。导致对同一条记录读取两次以上的结果不一致。

4.讲讲事务和MVCC底层原理详解:

比如现在有一个例子:

一个转账的一个案例:

丢失更新

两个事务针对同一数据都发生修改操作时,会存在丢失更新问题。

4.1解决方案:LBCC:

使用LBCC(LBCC,基于锁的并发控制,英文全称Lock Based Concurrency Control)可以解决上述的
问题。查询总额事务会对读取的行加锁,等到操作结束后再释放所有行上的锁。因为用户A的存款被锁,导致转账操作被阻塞,直到查询总额事务提交并将所有锁都释放。
示例:这种方案比较简单粗暴,就是一个事务去读取一条数据的时候,就上锁,不允许其他事务来操作
 
 

4.2:解决方案2:MVVC:

MVCC(MVCC,多版本的并发控制,英文全称:Multi Version Concurrency Control)机制可
以解决这个问题。查询总额事务先读取了用户A的账户存款,然后转账事务会修改用户A和用户B账户存
款,查询总额事务读取用户B存款时不会读取转账事务修改后的数据,而是读取本事务开始时的数据副本(在REPEATABLE READ隔离等级下)
只支持RC,RR隔离级别。
 
示例:MVCC使得数据库读不会对数据加锁,普通的SELECT请求不会加锁,提高了数据库的并发处理能力

5.Mysql的MVCC实现(重点):

  • MVCC是用于数据库提供并发访问控制的并发控制技术MVCC最大的好处:相信也是耳熟能详:读不加锁,读写不冲突。
  • 多版本并发控制仅仅是一种技术概念,并没有统一的实现标准,
  • 其核心理念就是数据快照,不同的事务访问不同版本的数据快照,从而实现不同的事务隔离级别。

5.1MVVC的实现机制:

mvvc是通过undo log+readview实现的:

undo log:

  • 是一个回滚日志就是提交一些未提交操作的原始状态 然后它会记录版本号 :
  • 如果有主键是2个隐藏列 如果没有则是3个隐藏列
  • 隐藏列呢就是三个部分组成
  • 1.rowid:如果没有主键则会自动生产
  • 2.回滚指针:指向记录的上一个版本号
  • 3.事务id:记录了操作这条事务的id(这个id是唯一的而且是自增的) 然后每次更新都会有生产一个新版本通过回滚指针指向旧版本 形成一个版本链
  • 执行删除操作的时候是不会直接删除的是进行了一个打了一个删除标记,真正删除是通过purge线程执行清除操作的

ReadView:

  • 相当于一个快照,只要readview不改变则读取的结果就是一样的

  • readview生产时刻就是执行select操作时生产的一个select对应一个ReadView select执行完毕那么ReadView就会失效
  • 它就是一个数组(m_ids) 记录了当前时刻数据库活跃的事务id列表,它的可见性判断呢可以根据m_ids与事务id进行判断 判断条件可以根据(如果都可读以最新版本为准):

  

句个列子比如:

如果数据库没有活跃的事务,那么ReadView(m_ids)中包含的就是将要生成的事务id。

在REPEATABLE READ(RR)隔离级别下,MVCC具体是如何操作的。

1.SELECT
InnoDB 会根据以下两个条件检查每行记录:
1. InnoDB只查找版本早于当前事务版本的数据行(也就是,行的事务编号小于或等于当前事务的事务编号)
 这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。
2. 删除的行要事务ID判断,读取到事务开始之前状态的版本。
只有符合上述两个条件的记录,才能返回作为查询结果。
2.INSERT
InnoDB为新插入的每一行保存当前事务编号作为行版本号。
3.DELETE
InnoDB为删除的每一行保存当前事务编号作为行删除标识。
4.UPDATE
InnoDB为插入一行新记录,保存当前事务编号作为行版本号,同时保存当前事务编号到原来的行作为行删除标识。

MVCC是如何解决隔离级别的呢?

RC事务隔离级别的实现:

读已提交:当前事务可以读取其他事务提交的结果

实现方案:当前事务执行select语句时会生产一个ReadView,如果再次执行这个selct语句继续生成ReadView。

RR事务隔离级别的实现:

可重复读:当前事务中执行的select语句的多次执行结果都是相同的,不管其他事务有没有提交。

实现方案:在当前事务执行select语句生产一个ReadView,之后同一个select使用同一个ReadView

RC和RR的区别:

  • READ COMMITTD 、 REPEATABLE READ 这两个隔离级别的一个很大不同就是生成 ReadView 的时机不同
  • READ COMMITTD 在每一次进行普通 SELECT 操作前都会生成一个 ReadView
  • 而 REPEATABLE READ 只在第一次进行普通 SELECT 操作前生成一个 ReadView ,之后的查询操作都重复这个 ReadView就好了。
  • 在REPEATABLE READ隔离级别下,MVCC具体是如何操作的。

MYSQL事务篇(高级篇)的更多相关文章

  1. 数据库MySQL学习笔记高级篇

    数据库MySQL学习笔记高级篇 写在前面 学习链接:数据库 MySQL 视频教程全集 1. mysql的架构介绍 mysql简介 概述 高级Mysql 完整的mysql优化需要很深的功底,大公司甚至有 ...

  2. 4 - 基于ELK的ElasticSearch 7.8.x技术整理 - 高级篇( 续 ) - 更新完毕

    0.前言 这里面一些理论和前面的知识点挂钩的,所以:建议看一下另外3篇知识内容 基础篇:https://www.cnblogs.com/xiegongzi/p/15684307.html java操作 ...

  3. 「MySQL高级篇」MySQL锁机制 && 事务

    大家好,我是melo,一名大三后台练习生,最近赶在春招前整理整理发过的博客~! 引言 锁锁锁,到哪到离不开这桩琐事,并发琐事,redis琐事,如今是MySQL琐事,这其中琐事,还跟MySQL另一个重要 ...

  4. 「MySQL高级篇」MySQL之MVCC实现原理&&事务隔离级别的实现

    大家好,我是melo,一名大三后台练习生,死去的MVCC突然开始拷打我! 引言 MVCC,非常顺口的一个词,翻译起来却不是特别顺口:多版本并发控制. 其中多版本是指什么呢?一条记录的多个版本. 并发控 ...

  5. 「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

    大家好,我是melo,一名大三后台练习生 专栏回顾 索引的原理&&设计原则 欢迎关注本专栏:MySQL高级篇 本篇速览 在我们上一篇文章中,讲到了索引的原理&&设计原则 ...

  6. 「 MySQL高级篇 」MySQL索引原理,设计原则

    大家好,我是melo,一名大二后台练习生,大年初三,我又来充当反内卷第一人了!!! 专栏引言 MySQL,一个熟悉又陌生的名词,早在学习Javaweb的时候,我们就用到了MySQL数据库,在那个阶段, ...

  7. 「MySQL高级篇」MySQL索引原理,设计原则

    大家好,我是melo,一名大二后台练习生,大年初三,我又来充当反内卷第一人了!!! 专栏引言 MySQL,一个熟悉又陌生的名词,早在学习Javaweb的时候,我们就用到了MySQL数据库,在那个阶段, ...

  8. 数据库篇:mysql事务原理之MVCC视图+锁

    前言 数据库的事务特性 数据并发读写时遇到的一致性问题 mysql事务的隔离级别 MVCC的实现原理 锁和隔离级别 关注公众号,一起交流,微信搜一搜: 潜行前行 1 数据库的事务特性 原子性:同一个事 ...

  9. PHP笔记(PHP高级篇)

    高级篇中将涉及数据库的使用以及Cookie和Session会话,提高PHP的开发效率和运行效率 PHP程序员需要掌握的MySQL操作 为项目设计表 使用SQL语句 MySQL的目录结构 data目录中 ...

  10. C#高级知识点&(ABP框架理论学习高级篇)——白金版

    前言摘要 很早以前就有要写ABP高级系列教程的计划了,但是迟迟到现在这个高级理论系列才和大家见面.其实这篇博客很早就着手写了,只是楼主一直写写停停.看看下图,就知道这篇博客的生产日期了,谁知它的出厂日 ...

随机推荐

  1. 西门子300PLC转以太网无需编程实现与1200PLC转以太网数据交换

    西门子300PLC转以太网无需编程实现与1200PLC转以太网数据通信 本文介绍利用兴达易控生产的PLC转以太网模块(MPI-ETH-XD1.0Plus)实现1200/1500PLC与300(CPU3 ...

  2. 20个最佳实践提升Terraform工作流程|Part 2

    在上一部分,我们一同探讨了构建 Terraform 项目的一些策略,以及使用 Terraform 管理 IaC 的部分最佳实践.今天,我们将继续深入研究将 Terraform 代码提升到新水平的具体要 ...

  3. 探秘公有IP地址与私有IP地址的区别及其在路由控制中的作用

    引言 IP地址是互联网通信中至关重要的组成部分.虽然在前一章节我们讲解了IP一些基础知识,但在我们日常生活中,我们经常听到公有IP地址和私有IP地址这两个术语.那么,公有IP地址和私有IP地址有何区别 ...

  4. jmeter生成随机英文的几种方法

    第一种:用BeanShell后置处理程序 1.写脚本 import java.util.Random; String random(int s_length) {       strings= &qu ...

  5. Python - 字典3

    修改字典项 您可以通过引用其键名来更改特定项的值: 示例,将 "year" 更改为 2018: thisdict = { "brand": "Ford ...

  6. JS中的caller属性

    JS中的caller属性: 这个属性会返回一个调用该函数对象的外层函数引用.也就是说,如果我们是在函数B()中调用函数A()的,那么只要在A()中调用A.caller,结果就会返回B()functio ...

  7. Go开发IDE全览:GoLand vs VSCode全面解析

    关注[TechLeadCloud],分享互联网架构.云服务技术的全维度知识.作者拥有10+年互联网服务架构.AI产品研发经验.团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构 ...

  8. 【MISC】[MoeCTF 2022]cccrrc --crc32爆破

    附件下载下来为压缩包,需要密码,查看该压缩包的内容 此处发现里面四个txt文件均已被加密,但是每个txt的内容都只有四个字节,符合crc32爆破条件,直接上脚本: import binascii im ...

  9. 开发一个现代化的.NetCore控制台程序,包含依赖注入/配置/日志等要素

    前言 最近需要开发小工具的场景有点多,上次我用 go 语言开发了一个 hive 导出工具,体验还不错,只是 go 语言的语法实在是喜欢不起来,这次继续试试用 C# 来开发小工具. 这次小工具的功能很简 ...

  10. JAVA中的函数接口,你都用过吗

    公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享. 在这篇文章中,我们将通过示例来学习 Java 函数式接口. 函数式接口的特点 只包含一个抽象方法的接口称为函数式接口. 它 ...