事物的隔离性

mysql的服务端是支持多个客户端同时与之连接的,每个客户端可能还并发了好几个连接,所以mysql是需要同时处理很多事情的,每一件独立的事情就叫做事务。我们知道事务有一个叫隔离性的特性,隔离性理论上是指在某个事物对某个数据进行访问时,其他的事务就应该排队知道访问数据的事务提交才能继续访问该数据。但是这样对性能的影响就太大了,但是我们又必须保持一定的隔离性,所以就需要折中一下。

事务并发可能的问题

先来看看不保证绝对的隔离性会遇到哪些问题呢

  • 脏写

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

  • 脏读

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

  • 不可重复读

如果同一个事务中能读到其他事务提交后的最新值,这时其他事务对这个数据进行的每次改动都会让该事务读到不同最新值,这就意味着发生了不可重复读。

  • 幻读

如果一个事务根据某些查出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,该事务再次用该条件查询的时候,就会查出上次查没查到的数据即另一个事务刚插入的数据,这就是幻读。

小贴士:

不可重复读和幻读确实有点相似,但不可重复读重点在于update和delete,而幻读的重点在于insert。对于前者,要避免只需锁住满足条件的已有记录即可,避免后者就需要锁住满足条件的记录(包括存在的和不存在的),不存在的记录如何才能锁住呢?所以锁的范围需要扩大到满足条件的相邻范围的记录(临键锁)

事务的隔离级别

这时就出现了一个标准用来定义上面说的折中的程度,在SQL标准中定义了4个隔离级别:

  • READ UNCOMMITTED:读未提交
  • READ COMMITTED:读已提交
  • REPEATABLE READ:可重复读
  • SERIALIZABLE:可串行化

SQL标准中规定,针对不同的隔离级别并发事务可以发生不同严重程度的问题

MVCC

MVCC解决了事务并发时读和写同时进行互不影响的问题,从而提升系统性能。mvcc并不能解决完全解决脏读和不可重复读的问题,如果innoDB只有mvcc没有锁,那么当前事务确实没办法读取到未提交的数据,但是可以修改。

对于读已提交和可重复读的事务来说,都必须保证读到的记录是已经提交了的事务修改的记录,所以如果想做到读写互不影响,核心问题就是读取记录时需判断版本链中的哪个版本是对当前事务可见。

MVCC原理

对于innoDB存储引擎来说,每张表中都含有两个必要的隐藏列trx_id和roll_pointer。每次对某条记录进行改动时,都会把旧的版本写入到 undo日志中,然后在这个roll_pointer列中存储旧版本在undo日志的地址,可以通过它来找到该记录修改前的信息,同时将进行改动的事务id写入trx_id列。

在可重复读的隔离模式下每个事务都会生成一个 ReadView ,主要包含4个重要的内容:

m_ids :表示在生成 ReadView 时当前系统中活跃的读写事务的 事务id 列表。

min_trx_id :表示在生成 ReadView 时当前系统中活跃的读写事务中最小的 事务id ,也就是

m_ids 中的最 小值。

max_trx_id :表示生成 ReadView 时系统中应该分配给下一个事务的 id 值。

creator_trx_id :表示生成该 ReadView 的事务的 事务id 。

有了这个 ReadView ,这样在访问某条记录时,只需要按照下边的步骤判断记录的某个版本是否可见:

如果被访问版本的 trx_id 属性值与 ReadView 中的 creator_trx_id 值相同,意味着当前事务在访问它自己 修改过的记录,所以该版本可以被当前事务访问。

如果被访问版本的 trx_id 属性值小于 ReadView 中的 min_trx_id 值,表明生成该版本的事务在当前事务生 成 ReadView 前已经提交,所以该版本可以被当前事务访问。

如果被访问版本的 trx_id 属性值大于 ReadView 中的 max_trx_id 值,表明生成该版本的事务在当前事务生 成 ReadView 后才开启,所以该版本不可以被当前事务访问。

如果被访问版本的 trx_id 属性值在 ReadView 的 min_trx_id 和 max_trx_id 之间,那就需要判断一下 trx_id 属性值是不是在 m_ids 列表中,如果在,说明创建 ReadView 时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建 ReadView 时生成该版本的事务已经被提交,该版本可以被访问。

如果某个版本的数据对当前事务不可见的话,那就顺着版本链找到下一个版本的数据,继续按照上边的步骤判断 可见性,依此类推,直到版本链中的最后一个版本。如果最后一个版本也不可见的话,那么就意味着该条记录对 该事务完全不可见,查询结果就不包含该记录。

上面两段引用来自于《MySQL是怎样运行的:从根儿上理解MySQL》,我觉得已经很明白了。

我写文章都是力求正确,但水平有限,欢迎大佬斧正。

相关资源:

MySQL是怎样运行的:从根儿上理解MySQL

事物的隔离性和MVCC的更多相关文章

  1. 事务传播性、隔离性与MVCC

    一.事务传播性 1.1 什么是事务的传播性 事务的传播性一般在事务嵌套时候使用,比如在事务A里面调用了另外一个使用事务的方法,那么这俩个事务是各自作为独立的事务执行提交,还是内层的事务合并到外层的事务 ...

  2. 一文搞懂MySQL事务的隔离性如何实现|MVCC

    关注公众号[程序员白泽],带你走进一个不一样的程序员/学生党 前言 MySQL有ACID四大特性,本文着重讲解MySQL不同事务之间的隔离性的概念,以及MySQL如何实现隔离性.下面先罗列一下MySQ ...

  3. 理解MySQL数据库事务-隔离性

    Transaction事务是指一个逻辑单元,执行一系列操作的SQL语句. 事务中一组的SQL语句,要么全部执行,要么全部回退.在Oracle数据库中有个名字,叫做transaction ID 在关系型 ...

  4. 跟面试官侃半小时MySQL事务隔离性,从基本概念深入到实现

    提到MySQL的事务,我相信对MySQL有了解的同学都能聊上几句,无论是面试求职,还是日常开发,MySQL的事务都跟我们息息相关. 而事务的ACID(即原子性Atomicity.一致性Consiste ...

  5. 数据库ACID、隔离级别与MVCC

    首先需要明确事务的概念:一组原子性的SQL查询,如果数据库引擎能够成功的对数据库应用该组查询的全部语句,那么就执行该组语句,否则所有语句都不执行. 事务有ACID四个特性,即: 原子性:一个事务是一个 ...

  6. MySQL:事务的隔离性

    [参考文章]:数据库的事务特性及隔离级别 1. 事务的四大特性 1.1 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用 ...

  7. MySQL四种隔离级别和MVCC

    事务在一个数据库中的地位尤为重要,尤其是高并发的场合.保证数据库操作的原子性和错误出现情况下的回滚,对数据的安全性和可靠性提供了保障.事务有四大原则,即ACID原则.网上关于这个问题的文章有很多,读者 ...

  8. SpringBoot 事务隔离性和传播性

    propergation 传播性 Spring中七种Propagation类的事务属性详解:  REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务.这是最常见的选择.  SUPPORTS ...

  9. 事务ACID特性,其中I代表隔离性(Isolation)。

    事务ACID特性,其中I代表隔离性(Isolation). 什么是事务的隔离性? 隔离性是指,多个用户的并发事务访问同一个数据库时,一个用户的事务不应该被其他用户的事务干扰,多个并发事务之间要相互隔离 ...

随机推荐

  1. C++ 炼气期之数据是主角

    1. 前言 数据在程序中的重要性,怎么强调都不为过,程序的本质就是通过提供数据处理逻辑,把数据从一种状态变成另一种状态的过程.处理逻辑一定是有针对性的,针对的是数据本身的特性. 只有了解了数据本身的内 ...

  2. alertmanager集群莫名发送resolve消息的问题探究

    alertmanager集群莫名发送resolve消息的问题探究 术语 告警消息:指一条告警 告警恢复消息:指一条告警恢复 告警信息:指告警相关的内容,包括告警消息和告警恢复消息 问题描述 最近遇到了 ...

  3. ABP Framework 5.3.0 版本新增功能和变更说明

    ABP Framework 5.3.0 稳定版已在2022年6月14日正式发布. 以下是本版本的新增功能: "开始"页面提供创建单层项目选项 启动模板提供 PWA 支持 Volo. ...

  4. CVPR2022 | 可精简域适应

    前言 在本文中,作者引入了一个简单的框架,即Slimmable Domain Adaptation,以通过权重共享模型库改进跨域泛化,从中可以对不同容量的模型进行采样,以适应不同的精度效率权衡.此外, ...

  5. Linux操作系统(2):组管理和权限管理

    组管理和权限管理 Outline 1.查看文件所有者:ls -ahl 2.更改文件或目录权限命令:chmod 3.更改文件或目录所有者命令:chown 4.更改文件或目录所属组命令:chgrp 1)组 ...

  6. shell脚本处理二进制数据

    正确处理二进制数据 正确处理二进制数据必须保证以下三个环节是二进制安全(Binary Safe)的: 从文件读取至内存: 处理数据过程中: 内存写入至文件. 那么二进制安全是什么?通俗来说就是不会特殊 ...

  7. 2022-7-14 java_2 第七组 刘昀航

    @ 目录 一.java约定规范 1.关于建包 2.控制台输入(Scanner) 关于Scanner的bug 计算器小练习: 二. 1.数组 建立数组的三种方式: 数据类型的初始值: 2.二维数组 使用 ...

  8. osi七层与TCP\IP协议

    层次划分的方法 1.网络的每层应当具有相对独立的功能(便于排错)这个功能用不了必然是你这层处理问题 2.梳理功能之间的关系,使上一个功能可以实现为另一个功能提供必要的服务,从而形成系统的层次结构.为提 ...

  9. filebeat + logstash 日志采集链路配置

    1. 概述 一个完整的采集链路的流程如下: 所以要进行采集链路的部署需要以下几个步聚: nginx的配置 filebeat部署 logstash部署 kafka部署 kudu部署 下面将详细说明各个部 ...

  10. Pandas简单操作(学习总结)

    Pandas 的主要数据结构是 Series (一维数据)与 DataFrame(二维数据),是一个提供高性能.易于使用的数据结构和数据分析工具. 接下来查看Pandas的基本使用: # 导入模块 i ...