Mysql事务篇——Day02

news2024/10/5 13:16:56

Mysql事务篇——Day02

  • 事务有哪些特性
  • 并发事务引发的问题
    • 脏读
    • 不可重复读
    • 幻读
  • 事务隔离级别
  • Read View 在 MVCC里如何工作

事务有哪些特性

事务是依赖MySQL的储存引擎是实现的,我们常见的Innodb引擎就是支持事务的。
不过并不是所有的存储引擎都可以支持事务,比如MySQL原生的MyISAM就不支持事务,也正是这样,所以大多数的MySQL引擎用的都是innodb。

事务看起来很简单,但是要实现事务必须遵循4个特性:

  1. 原子性
    一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间的某一步,而且事务在执行的过程中发生错误,会回滚到事务开始前的状态,就行这个事务从哥俩没有执行过一样。
  2. 一致性
    指事务操作前后,数据满足完整性约束,数据库保持一致性,比如转账,用户A和用户B分别在银行存有800和600元,总共1400元,不管如何转账,总钱数必须是1400。
  3. 隔离性
    数据库允许多个并发事务同时及对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据不一致,因为多个事务同时使用相同的数据时,不会相互干扰,每个事务都有自己一个空间,对其他并发事务是隔离的。
  4. 持久性
    事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失数据。
  • 事务的持久性是通过redo log来保证的
  • 事务的原子性是通过undo log来保证的
  • 事务的隔离性是通过Mvcc 或者锁机制来保证的
  • 事物的一致性是通过持久性+原子性+隔离性来保证的

并发事务引发的问题

Mysql 服务端是允许多个客户端连接的,这意味着MySQL会有同时处理多个事务情情况。
那么在同时处理多个事务的时候就可能出现脏读、不可重复读、幻读的问题。

脏读

如果一个事务读到了另一个事务未提交数据修改过的数据,就意味着发生了脏读的现象。

假设A和B两个事务同时在处理,事务A先从数据库中读取小林的余额数据,然会再执行更新操作,如果这时候A还没有提交事务,而此时正好B也从数据库中读取小c的余额数据,那么事务B读取到的余额数据就是事务A更新后的数据,即使没有提交事务。
在这里插入图片描述
因为事务A是还没有提交事务的,也就是它随时可能发生回滚操作,如果上面这种情况出现了事务A发生了回滚,那么事务B方才得到的数据库就是脏数据,这种现象就叫做脏读。

不可重复读

在一个事务内多次读取同一个数据,如果出现前后两次数据不一致的现象,就意味着发生了不可重复读。
假设A和B两个事务同时在处理,事务A开始先从数据库读取小c余额,然后继续执行代码处理逻辑,在这个过程中如果事务B更新了这条数据,并且提交了事务,那么事务A再次读取该数据的时候,就会发现亲后两次读取到的数据是不一致的,这种现象就叫做不可重复读。
在这里插入图片描述

幻读

在一个事务内多次查询某个符合查询条件的记录数量,如果前后两次查询到的记录数不一样,就意味着出现了幻读现象。

假设有 A 和 B 这两个事务同时在处理,事务 A 先开始从数据库查询账户余额大于 100 万的记录,发现共有 5 条,然后事务 B 也按相同的搜索条件也是查询出了 5 条记录。
2
接下来,事务 A 插入了一条余额超过 100 万的账号,并提交了事务,此时数据库超过 100 万余额的账号个数就变为 6。

然后事务 B 再次查询账户余额大于 100 万的记录,此时查询到的记录数量有 6 条,发现和前一次读到的记录数量不一样了,就感觉发生了幻觉一样,这种现象就被称为幻读。

事务隔离级别

上面我们说到,多个是事务并发执行可能会遇到的问题,这些问题会对事务的一致性产生不同的影响。

  • 脏读:读到其他事务未提交的数据
  • 不可重复读:前后读取到的数据不一致
  • 幻读:前后读取到的记录数不一致

SQL标准提供了四种隔离级别来规避这些问题:

  1. 读未提交(read uncommitted),指一个事务还没提交时,它做的变更就能被其他事务看到;
  2. 读提交(read committed),指一个事务提交之后,它做的变更才能被其他事务看到;
  3. 可重复读(repeatable read),指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,MySQL InnoDB 引擎的默认隔离级别;
  4. 串行化(serializable );会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;

针对不同的隔离级别,并发事务时可能发生的现象也会不同。
在这里插入图片描述
也就是说:

在读未提交隔离级别下,可能发生脏读、不可重复读和幻读现象;
在读提交隔离级别下,可能发生不可重复读和幻读现象,但是不可能发生脏读现象;
在可重复读隔离级别下,可能发生幻读现象,但是不可能脏读和不可重复读现象;
在串行化隔离级别下,脏读、不可重复读和幻读现象都不可能会发生。
所以,要解决脏读现象,就要升级到读提交以上的隔离级别;要解决不可重复读现象,就要升级到可重复读的隔离级别,要解决幻读现象不建议将隔离级别升级到串行化。

不同的数据库厂商对 SQL 标准中规定的 4 种隔离级别的支持不一样,有的数据库只实现了其中几种隔离级别,我们讨论的 MySQL 虽然支持 4 种隔离级别,但是与SQL 标准中规定的各级隔离级别允许发生的现象却有些出入。

MySQL 在可重复读隔离级别下,可以很大程度上避免幻读现象的发生(注意是很大程度避免,并不是彻底避免),但是 MySQL 并不会使用串行化隔离级别来避免幻读现象的发生,因为使用串行化隔离级别会影响性能。

MySQL InnoDB 引擎的默认隔离级别虽然是可重复读,但是它很大程度上避免幻读现象,那么如何让解决幻读问题呢?:

  1. 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好了避免幻读问题。
  2. 针对当前读(select … for update 等语句),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读,因为当执行 select … for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。

这四种隔离级别是如然后实现的呢?

  • 对于读未提交隔离级别的事务来说,因为可以读取到未提交事务修改的数据,所以直接读取最新数据就可以;
  • 对于串行化隔离级别的事务来说,通过加读写锁的方式来避免并行访问;
  • 对于读已提交和可重复读隔离级别的事务来说,他们是通过Read View来实现的,他们的区别在于创建Read View 的时机不同,大家可以把Read View 理解成以恶搞数据快照,就像相机拍照,读已提交是在每个语句执行前都会重新生成一个Read View ,而可重复读是在启动时事务时生成一个Read View,然后整个事务期间都是用这个Read View。
    注意:执行开始事务命令,并不意味着启动了十五,在MySQL有两种开启事务的方式,
  1. begin / start transaction
  2. start / transcation with consistent snapshot

这两种事务启动的方式,启动时机是不同的,第一种执行命令后只有在执行了增删改查操作后才会穷事务,第二种是直接启动。

Read View 在 MVCC里如何工作

我们需要知道两个知识,第一,Read View四个字段的作用;第二,聚簇索引记录中两个和事务有关的隐藏列。

什么是Read View:
在这里插入图片描述
Read View 有四个重要的字段:

  • m_ids :指的是在创建 Read View 时,当前数据库中「活跃事务」的事务 id 列表,注意是一个列表,“活跃事务”指的就是,启动了但还没提交的事务。
  • min_trx_id :指的是在创建 Read View 时,当前数据库中「活跃事务」中事务 id 最小的事务,也就是 m_ids 的最小值。
  • max_trx_id :这个并不是 m_ids 的最大值,而是创建 Read View 时当前数据库中应该给下一个事务的 id 值,也就是全局事务中最大的事务 id 值 + 1;
  • creator_trx_id :指的是创建该 Read View 的事务的事务 id。

知道了 Read View 的字段,我们还需要了解聚簇索引记录中的两个隐藏列。
在这里插入图片描述

  • trx_id,当一个事务对某聚簇索引记录进行改动时,就会把该事务id记录在trx_id隐藏列中;
  • roll_pointer,每次对某条聚簇索引记录进行改动时,就会把旧版本的记录写入到uodo日志中,然后够这个隐藏列是一个指针,指向上一个旧版本记录,可以通过它找到修改前的记录。
    在创建Read View后,我们可以将记录中的trx_id划分为三种情况:
    在这里插入图片描述
    一个事务去访问记录的时候,除了自己的更新记录总是可见之外,还有几种情况:
  1. 如果记录的trx_id小于Read View中的min_trx_id值,表示这个版本的记录是在创建Read View之前已经提交的事务生成的,所以该版本的记录对当前事务可见。
  2. 如果该版本记录的trx_id大于等用途Read View中的max_trx_id值,表示这个版本的记录是在创建Read View后才启动的事务生成的,所以该版本的额记录对当前事务不可见。
  3. 如果记录的trx_id在Read View的min_trx_id和max_trx_id之间,需要判断trx_id是否在m_ids列表中:
    • 如果记录的trx_id在m_ids列表中,表示生成该版本记录的事务依然活跃着(还没有提交事务),所以该版本的记录对当前事务不可见。
    • 如果记录的trx_id不在m_ids列表中,表示生成该版本记录的事务已经被提交,所以该版本的记录对当前事务可见。

这种通过「版本链」来控制并发事务访问同一个记录时的行为就叫 MVCC(多版本并发控制)。

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

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

相关文章

SecureCRT8.5安装教程

第一步: 将文件下载解压 第二步: 双击进行安装,或者右键以管理员的方式运行 第三步: 直接点下一步 第四步: 选择接受协议,然后点下一步 第五步: 我这里选择所有用户,然后点下一…

js实现按创建时间戳1609459200000 开始往后开始显示运行时长-demo

运行时长 00日 00时 17分 59秒 代码 function calculateRuntime(timestamp) {const startTime Date.now(); // 获取当前时间戳//const runtimeElement document.getElementById(runtime); // 获取显示运行时长的元素function updateRuntime() {const currentTimestamp Date…

spring入门基本介绍及注入方式---详细介绍

一,spring的简介 Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。 提供了许多功能强大且易于使用的特性,使得开发者能够更加轻松地构建可维护且可扩展的应用程序,简单来说: Spring使用基…

攻击LNMP架构Web应用

环境配置(centos7) 1.php56 php56-fpm //配置epel yum install epel-release rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm//安装php56,php56-fpm及其依赖 yum --enablereporemi install php56-php yum --enablereporemi install php…

深入了解唯品会API及其应用

随着电商行业的快速发展,API(Application Programming Interface,应用程序接口)已经成为许多企业实现系统对接、数据交换和功能扩展的重要工具之一。唯品会作为国内领先的电商平台之一,也提供了丰富的API接口&#xff…

component:()=>import(“@/views/Home.vue“) 报错,ts说没有找到类型声明文件

1 没有写.vue文件的类型声明,要在env.d.ts文件中写.vue的类型声明文件 2 ts.config.josn的incluede字段中,没有把.d.ts文件的路径写对。 如果没写对,就会在项目启动的时候,找不到.d.ts文件。找不到类型声明文件

【自动电压调节器】无功功率控制的终端电压控制研究(Simulink)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

ATF(TF-A)安全通告 TFV-5 (CVE-2017-15031)

安全之安全(security)博客目录导读 ATF(TF-A)安全通告汇总 目录 一、ATF(TF-A)安全通告 TFV-5 (CVE-2017-15031) 二、CVE-2017-15031 一、ATF(TF-A)安全通告 TFV-5 (CVE-2017-15031) Title 未初始化或保存/恢复PMCR_EL0可能会泄露安全世界的时间信息 CVE ID CVE-2017-1503…

cs231n assignment 3 Q2 Image Captioning with Vanilla RNNs

文章目录 嫌啰嗦直接看代码Q2 Image Captioning with Vanilla RNNs一个给的工具代码里的bug问题展示问题解决思路解决办法 rnn_step_forward题面解析代码输出 rnn_step_backward题面解析代码输出 rnn_forward题面解析代码输出 rnn_backward题面解析代码输出 word_embedding_for…

时序预测 | MATLAB实现基于CNN-BiLSTM卷积双向长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)

时序预测 | MATLAB实现基于CNN-BiLSTM卷积双向长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价) 目录 时序预测 | MATLAB实现基于CNN-BiLSTM卷积双向长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)预测结果基本介绍程序设计参考资料 预测结果 基本介绍…

leetcode 518. 零钱兑换 II

本题是背包问题系列的完全背包问题,和0-1背包唯一的区别就在于:物品是可以重复选取的。 经过之前背包问题的拷打,本题也是一遍AC了。 接下来将给出二维和一维两种做法。 二维dp数组做法: 本题的背包大小即为题中给出的总金额&am…

与微软Office抗衡,两大巨头布局,打造新办公软件,再上新台阶

办公软件是我们日常工作中不可或缺的工具。 除了广为人知的微软Office套件外,近几年来,中国市场有许多优秀的国产办公软件抢眼登场,这些软件在提高工作效率、简化工作流程方面发挥着重要作用。 简单介绍几款值得知道的国产办公软件&#xff…

【学习FreeRTOS】第9章——FreeRTOS任务调度

1.开启任务调度器 vTaskStartScheduler() 作用:用于启动任务调度器,任务调度器启动后, FreeRTOS 便会开始进行任务调度【动态创建任务为例】 创建空闲任务如果使能软件定时器,则创建定时器任务关闭中断,防止调度器开…

99%的Python用户都不知道的f-string隐秘技巧

f-string想必很多Python用户都基础性的使用过,作为Python3.6版本开始引入的特性,通过它我们可以更加方便地向字符串中嵌入自定义内容,但f-string真正蕴含的功能远比大多数用户知道的要丰富,今天我们就来一起get它们~ 「最基础用法…

JVS开源基础框架:平台基本信息介绍

JVS是面向软件开发团队可以快速实现应用的基础开发脚手架,主要定位于企业信息化通用底座,采用微服务分布式框架,提供丰富的基础功能,集成众多业务引擎,它灵活性强,界面化配置对开发者友好,底层容…

MySQL性能分析之慢查询日志查看

一、背景 MySQL的慢查询日志是MySQL提供的一种日志记录,他用来记录在MySQL中响应的时间超过阈值的语句,具体指运行时间超过long_query_time(默认是10秒)值的SQL,会被记录到慢查询日志中。 慢查询日志一般用于性能分析时开启,收集慢SQL然后通过explain进行全面分析,一…

GPU Dissolve(GPU 消散)学习GPU Instancing

一:摘要 通过制作一个模型GPU消散效果来学习GPU Instancing 也就是实例化。 目标效果是杨超大佬文章《GPU shatter》里面的消散效果如图: Tags:模型顶点分裂(Mesh Vertex Splitting), 实例化绘制(GPU Instancing Drawing)&#x…

【100天精通python】Day36:GUI界面编程_高级功能操作和示例

专栏导读 专栏订阅地址:https://blog.csdn.net/qq_35831906/category_12375510.html 一、GUI 高级功能 1 自定义主题和样式 自定义主题和样式可以让你的GUI应用程序在外观方面更加出色。在使用Tkinter时,你可以使用ttkthemes库来应用不同的主题和样式。…

一文搞懂Spring是如何解决Bean循环依赖的?

一.什么是Bean循环依赖 循环依赖是指Bean对象循环引用,是两个或多个Bean之间相互持有对方的引用,循环依赖有2中表现形式 第一种相互依赖,就是A依赖B,B又依赖A 第二种是自我依赖,就是A依赖自己形成自我依赖 对象引用…

上山取石,下江取锦。诗人秋浦啸傲,新津樵唱。江南山水秀美,水乡文化流长。而水,则是这些山水风景的灵魂所在。 水,雨露滋润万物生长的泉源。 它潺潺流淌于山间溪涧,涓涓细流化成了青山的眼泪。水顺势而下&a…