Mysql中事务ACID实现原理

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

面试官:“知道事务的四大特性么?”
你:“懂,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元,分别在两个事务中执行。如果无法保证隔离性,会出现下面的情形
Mysql中事务ACID实现原理

如图所示,如果不保证隔离性,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三大特性,才有可能实现一致性。例如,原子性无法保证,显然一致性也无法保证。

但是,如果你在事务里故意写出违反约束的代码,一致性还是无法保证的。例如,

  • 8
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值