照例,我们先来一个场景~

面试官:"知道事务的四大特性么?"
你:"懂,ACID嘛,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)!"
面试官:“你们是用mysql数据库吧,能简单说说innodb中怎么实现这四大特性的么?”
你:"我只知道隔离性是怎么做的balabala~~"
面试官:"还是回去等通知吧~"

OK,回到正题。说到事务的四大特性原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),懂的人很多。但是稍微涉及细节一点,这四大特性在数据库中的实现原理是怎么样的?那就没有几个人能够答得上来了。因此,我们这篇文章着重讨论一下四大特性在Mysql中的实现原理。

正文

我们以从A账户转账50元到B账户为例进行说明一下ACID,四大特性。

原子性

根据定义,原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做。即要么转账成功,要么转账失败,是不存在中间的状态!
如果无法保证原子性会怎么样?
OK,就会出现数据不一致的情形,A账户减去50元,而B账户增加50元操作失败。系统将无故丢失50元~

隔离性

根据定义,隔离性是指多个事务并发执行的时候,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
如果无法保证隔离性会怎么样?
OK,假设A账户有200元,B账户0元。A账户往B账户转账两次,金额为50元,分别在两个事务中执行。如果无法保证隔离性,会出现下面的情形

如图所示,如果不保证隔离性,A扣款两次,而B只加款一次,凭空消失了50元,依然出现了数据不一致的情形!

ps:可能有细心的读者已经发现了,mysql中是依靠锁来解决隔离性问题。嗯,我们后面来说明。

持久性

根据定义,持久性是指事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

如果无法保证持久性会怎么样?
在Mysql中,为了解决CPU和磁盘速度不一致问题,Mysql是将磁盘上的数据加载到内存,对内存进行操作,然后再回写磁盘。好,假设此时宕机了,在内存中修改的数据全部丢失了,持久性就无法保证。

设想一下,系统提示你转账成功。但是你发现金额没有发生任何改变,此时数据出现了不合法的数据状态,我们将这种状态认为是数据不一致的情形。

一致性

根据定义,一致性是指事务执行前后,数据处于一种合法的状态,这种状态是语义上的而不是语法上的。
那什么是合法的数据状态呢?
oK,这个状态是满足预定的约束就叫做合法的状态,再通俗一点,这状态是由你自己来定义的。满足这个状态,数据就是一致的,不满足这个状态,数据就是不一致的!

如果无法保证一致性会怎么样?
例一:A账户有200元,转账300元出去,此时A账户余额为-100元。你自然就发现了此时数据是不一致的,为什么呢?因为你定义了一个状态,余额这列必须大于0。
例二:A账户200元,转账50元给B账户,A账户的钱扣了,但是B账户因为各种意外,余额并没有增加。你也知道此时数据是不一致的,为什么呢?因为你定义了一个状态,要求A+B的余额必须不变。

实战解答

问题一:Mysql怎么保证一致性的?

OK,这个问题分为两个层面来说。
从数据库层面,数据库通过原子性、隔离性、持久性来保证一致性。也就是说ACID四大特性之中,C(一致性)是目的,A(原子性)、I(隔离性)、D(持久性)是手段,是为了保证一致性,数据库提供的手段。数据库必须要实现AID三大特性,才有可能实现一致性。例如,原子性无法保证,显然一致性也无法保证。

但是,如果你在事务里故意写出违反约束的代码,一致性还是无法保证的。例如,你在转账的例子中,你的代码里故意不给B账户加钱,那一致性还是无法保证。因此,还必须从应用层角度考虑。

从应用层面,通过代码判断数据库数据是否有效,然后决定回滚还是提交数据!

问题二: Mysql怎么保证原子性的?

OK,是利用Innodb的undo log。
undo log名为回滚日志,是实现原子性的关键,当事务回滚时能够撤销所有已经成功执行的sql语句,他需要记录你要回滚的相应日志信息。
例如

1、当你delete一条数据的时候,就需要记录这条数据的信息,回滚的时候,insert这条旧数据

2、当你update一条数据的时候,就需要记录之前的旧值,回滚的时候,根据旧值执行update操作

3、当年insert一条数据的时候,就需要这条记录的主键,回滚的时候,根据主键执行delete操作

undo log记录了这些回滚需要的信息,当事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。

ps:具体的undo log日志长啥样,这个可以写一篇文章了。而且写出来,看的人也不多,姑且先这么简单的理解吧。

问题三: Mysql怎么保证持久性的?

OK,是利用Innodb的redo log。
正如之前说的,Mysql是先把磁盘上的数据加载到内存中,在内存中对数据进行修改,再刷回磁盘上。如果此时突然宕机,内存中的数据就会丢失。 怎么解决这个问题? 简单啊,事务提交前直接把数据写入磁盘就行啊。 这么做有什么问题?

  • 只修改一个页面里的一个字节,就要将整个页面刷入磁盘,太浪费资源了。毕竟一个页面16kb大小,你只改其中一点点东西,就要将16kb的内容刷入磁盘,听着也不合理。
  • 毕竟一个事务里的SQL可能牵涉到多个数据页的修改,而这些数据页可能不是相邻的,也就是属于随机IO。显然操作随机IO,速度会比较慢。

于是,决定采用redo log解决上面的问题。当做数据修改的时候,不仅在内存中操作,还会在redo log中记录这次操作。当事务提交的时候,会将redo log日志进行刷盘(redo log一部分在内存中,一部分在磁盘上)。当数据库宕机重启的时候,会将redo log中的内容恢复到数据库中,再根据undo log和binlog内容决定回滚数据还是提交数据。

采用redo log的好处? 其实好处就是将redo log进行刷盘比对数据页刷盘效率高,具体表现如下

  • redo log体积小,毕竟只记录了哪一页修改了啥,因此体积小,刷盘快。
  • redo log是一直往末尾进行追加,属于顺序IO。效率显然比随机IO来的快。

ps:不想具体去谈redo log具体长什么样,因为内容太多了。

问题四: Mysql怎么保证隔离性的?

OK,利用的是锁和MVCC机制。还是拿转账例子来说明,有一个账户表如下
表名t_balanc

其中id是主键,user_id为账户名,balance为余额。还是以转账两次为例,如下图所示

至于MVCC,即多版本并发控制(Multi Version Concurrency Control),一个行记录数据有多个版本对快照数据,这些快照数据在undo log中。

如果一个事务读取的行正在做DELELE或者UPDATE操作,读取操作不会等行上的锁释放,而是读取该行的快照版本。
由于MVCC机制在可重复读(Repeateable Read)和读已提交(Read Commited)的MVCC表现形式不同,就不赘述了。
但是有一点说明一下,在事务隔离级别为读已提交(Read Commited)时,一个事务能够读到另一个事务已经提交的数据,是不满足隔离性的。但是当事务隔离级别为可重复读(Repeateable Read)中,是满足隔离性的。

总结

本文讲了Mysql中事务ACID四大特性的实现原理,希望大家有所收获。

转自:https://zhuanlan.zhihu.com/p/65438009

MySQL事务ACID实现原理相关推荐

  1. 五、Mysql事务以及锁原理

    五.Mysql事务以及锁原理 事务(ACID) 场景:小明向小强转账10元 原子性(Atomicity) 转账操作是一个不可分割的操作,要么转失败,要么转成功,不能存在中间的状态,也就是转了一半的这种 ...

  2. 《深入理解分布式事务》第二章 MySQL 事务的实现原理

    shua# <深入理解分布式事务>第二章 MySQL 事务的实现原理 文章目录 一.Redo Log 1.Redo Log 基本概念 2.Redo Log 基本原理 3.Redo Log ...

  3. mysql中decimal不能为空吗_程序员,知道Mysql中事务ACID的原理吗?

    点击上方"linkoffer", 选择关注公众号高薪职位第一时间送达 引言 照例,我们先来一个场景~ 面试官:"知道事务的四大特性么?" 你:"懂,A ...

  4. mysql事务ACID原理MVCC 幻读

    文章目录 mysql事务原理MVCC 1存储引擎 1.InnoDB存储引擎 2.MyISAM存储引擎 2.undo和redo的功能 undo: redo: 3.mysql锁 3.1表级锁 3.2行级锁 ...

  5. 天天用事务,但是你知道MySQL事务的实现原理吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:rrd.me/fDv2c 1. 开篇 相信大家都用过事务以及 ...

  6. mysql 事务值被改变_面试被问MySQL 事务的实现原理,怎么破?

    Java面试笔试面经.Java技术每天学习一点 作者:小小木的博客 来源:https://www.cnblogs.com/wyc1994666/ 开篇 相信大家都用过事务以及了解他的特点,如原子性(A ...

  7. 面试刷题29:mysql事务隔离实现原理?

    mysql的事务是innodb存储引擎独有的,myisam存储引擎不支持事务. 事务最经典的例子就是转账了,事务要保证的是一组数据库的操作要么全部成功,要么全部失败.是为了保证高并发场景下数据的正确性 ...

  8. mysql数据库ACID实现原理

    说到事物的四大特性原子性.一致性.隔离性.持久性,懂的人很多,但是稍微涉及细节,四大特性在数据库中的实现原理是怎么实现的?几乎很少有人能够答上来.所以这里着重讨论下mysql中的实现原理. 问题一:M ...

  9. 详述MySQL事务的实现原理

    相信大家都用过事务以及了解他的特点,如原子性(Atomicity),一致性(Consistency),隔离型(Isolation)以及持久性(Durability)等.今天想跟大家一起研究下事务内部到 ...

最新文章

  1. IntelliJ IDEA 环境常用设置整理
  2. python爬虫 django搜索修改更新数据_一文搞懂Django数据库查询操作
  3. 全网最细节的sds讲解,轻松拿下offer
  4. 在Silverlight中读取指定URL图片包数据
  5. 解决ubuntu下pdf中文不显示或乱码问题
  6. URI和URL、URN的区别
  7. java注解枚举转换器_java – Annotation处理器:从TypeMirror或TypeElement获取所有枚举值...
  8. PIC单片机学习-中断
  9. 计算机485通讯原理,用RS-485设计的多机通信接口电路
  10. Codeforces Round #739 (Div. 3) E. Polycarp and String Transformation
  11. 4.3.2 Calculating and Applying VaR
  12. 解决浏览器下载速度慢的问题
  13. iPhone手机总是弹出输入ID密码怎么办?
  14. MySQL插入数据库乱码问题Incorrect string value: ‘\xE8\xB5\xB5‘ for column ‘name‘ at row 1
  15. Java LocalDateTime给当前时间加半小时
  16. 球球音响机器人怎么合成的_PS合成机器人教程
  17. far指针与near指针
  18. 最难php框架,PHP框架发展存四误区 死穴不除难成大器
  19. 奋进新时代 和数BaaS开启下一个波澜壮阔科技新世界
  20. 游戏服务器 协议安全,游戏服务器 协议安全

热门文章

  1. openLayer加载KML,画出省及省下的边界区域,并设置样式、各种标注及提示信息
  2. 摘:多线程和异步的区别
  3. 将表数据生成SQL脚本的存储过程和工具
  4. 诗与远方:无题(三十五)- 曾经写给妹子的一首诗
  5. 工作两年多的一个菜鸟感想
  6. Linux超简单文本编辑器:nano
  7. Fences桌面图标分类
  8. Hibernate之DetachedCriteria类详解
  9. 灾备中心服务器辐射,数据中心和灾备中心的相同点以及不同点
  10. 深入理解Java main方法