精华内容
下载资源
问答
  • acid四大特性
    2021-06-16 21:32:49
    • A 原子性
      指的是一个事务是一个独立的整体,要么完全操作成功,要么完全失败
    • I 隔离性
      指的是并发控制的时候,事务与事务之间相互不影响,防止并发导致数据不一致,一般通过通过乐观锁和悲观锁实现
    • D 持久性
      指的是数据一旦提交,将永久改变数据库中的数据
    • C 一致性
      事务和系统处于一致的状态
      其中一致性最不好理解,举个例子来说:一致性就是我给我同学转账100元,他如果接受到这个钱,我账户里就少了100元,而他的账户则必须要多100块,符合”守恒“,-100+100=0结果和原来没转帐之前是一样的
    更多相关内容
  • 数据库ACID四大特性到底为了啥,一文带你看通透

    千次阅读 多人点赞 2021-05-06 13:44:38
    说起数据库四大特性,同学们张口就来,ACID!那为什么要ACID?每种特性的原理又是什么?如何实现的?废话少说,哈哥今天带你搞清楚,快上车!

    小伙伴想精准查找自己想看的MySQL文章?喏 → MySQL江湖路 | 专栏目录

      说起数据库四大特性,同学们张口就来,ACID!那为什么要ACID?每种特性的原理又是什么?如何实现的?废话少说,哈哥今天带你搞清楚,快上车!
      ACID,是用来声明数据库事务的四大特性,即原子性 (Atomicity)、 一致性(Consistency)、隔离性(Isolation) 和 持久性(Durability)

    在这里插入图片描述

    谈谈个人理解

      简单说,事务就是一组原子性的SQL执行单元。如果数据库引擎能够成功地对数据库应 用该组査询的全部语句,那么就执行该组SQL。如果其中有任何一条语句因为崩溃或其 他原因无法执行,那么所有的语句都不会执行。要么全部执行成功(commit),要么全部执行失败(rollback)

      这里引用银行转账的例子,假设银行的数据库有两张表:信用卡(credit)表和储蓄(savings)表。用户陈哈哈要把信用卡里最后100块钱额度转到他 的储蓄账户用来吃饭,那么需要至少三个步骤:

    1. 检査信用卡余额是否髙于100块钱。
    2. 从信用卡账户余额中减去100块钱。
    3. 在储蓄账户余额中增加100块钱。

      上述三个步骤必须在同一个事务中执行,任何一个SQL失败,则必须回滚所有的SQL。这里用START TRANSACTION语句开启事务,要么使用COMMIT提交事务将修改的数据持久保留,要么使用ROLLBACK销所有的修改。事务SQL的样本如下:

    START TRANSACTION;
    -- 检查信用卡账户额度
    SELECT balance FROM credit WHERE customer_id = 'chenhh';
    -- 信用卡表扣钱
    UPDATE credit SET balance = balance - 100.00 WHERE customer_id = 'chenhh';
    -- 储蓄表加钱
    UPDATE savings SET balance = balance + 100.00 WHERE customer_id = 'chenhh';
    COMMIT;
    

      试想一下,如果执行到第四条语句时服务器崩溃了,会发生什么?废话,我被坑了100块钱,中午只能饿肚子!再假如,在执行到第三条语句和第四 条语句之间时,同一时间,另外一个进程,来自商场结账的女朋友,也要信用卡账户的100块,那么结果可能就是银行在不知道这个逻辑的情况下白白给了陈哈哈女朋友100块钱?

    在这里插入图片描述

      别做梦了,主流关系型数据库(如MySQL、Oracle等)是通过了严格的ACID测试,不会随便出这种BUG的。那么我们今天就一起来搞懂ACID的核心原理。

    一、ACID特性

    • 原子性(Atomicity)

      单个事务,为一个不可分割的最小工作单元,整个事务中的所有操作要么全部commit成功,要么全部失败rollback,对于一个事务来说,不可能只执行其中的一部分SQL操作,这就是事务的原子性。

    • 一致性(Consistency)

      数据库总是从一个一致性的状态转换到另外一个一致性的状态。在前面的例子中, 一致性确保了,即使在执行第三、四条语句之间时系统崩潰,信用卡账户也不会损 失100块,因为事务最终没有提交,所以事务中所做的修改也不会保存到数据库中,保证数据一致性。

    • 隔离性(Isolation)

      通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。在前面 的例子中,当执行完第三条语句、第四条语句还未开始时,此时有另外一个账户查询余额SQL开始运行,则其看到的信用卡账户的余额并没有被减去100元。后面我们讨论隔离级别(Isolation level)的时候,会发现为什么我们要说事务通常来说是不可见的

    • 持久性(Durability)

      一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。

      事务的ACID特性可以确保银行不会弄丢你的钱。而在应用逻辑中,要实现这一点非常难, 甚至可以说是不可能完成的任务。一个兼容ACID的数据库系统,需要做很多复杂但可能用户并没有觉察到的工作,才能确保ACID的实现。

    二、ACID具体实现

      对MySQL来说,逻辑备份日志(binlog)、重做日志(redolog)、回滚日志(undolog)、锁技术 + MVCC就是MySQL实现事务的基础

    • 原子性:通过undolog来实现。
    • 持久性:通过binlog、redolog来实现。
    • 隔离性:通过(读写锁+MVCC)来实现。
    • 一致性:MySQL通过原子性,持久性,隔离性最终实现(或者说定义)数据一致性。

    学习MySQL日志可参考《听我讲完redo log、binlog原理,面试官老脸一红》
    学习MySQL锁机制可参考 《面试让HR都能听懂的MySQL锁机制,欢声笑语中搞懂MySQL锁》

    1、原子性原理

    事务通常是以BEGIN TRANSACTION 开始,以 COMMIT 或 ROLLBACK 结束。

    • COMMIT 表示提交,即提交事务的所有操作并持久化到数据库中。
    • ROLLBACK表示回滚,即在事务中运行的过程中发生了某种故障,事务不能继续执行,系统将事务中对数据库所有已完成的操作全部撤销,回滚到事务开始时的状态,这里的操作指对数据库的更新操作,已执行的查询操作不用管。这时候也就需要用到 undolog 来进行回滚。

    undolog:

    1. 每条数据变更(INSERT/UPDATE/DELETE/REPLACE)等操作都会生成一条undolog记录,在SQL执行前先于数据持久化到磁盘。
    2. 当事务需要回滚时,MySQL会根据回滚日志对事务中已执行的SQL做逆向操作,比如 DELETE 掉一行数据的逆向操作就是再把这行数据 INSERT回去,其他操作同理。

    2、持久性原理

      先了解一下MySQL的数据存储机制,MySQL的表数据是存放在磁盘上的,因此想要存取的时候都要经历磁盘 IO,然而即使是使用 SSD 磁盘 IO 也是非常消耗性能的。为此,为了提升性能 InnoDB 提供了缓冲池(Buffer Pool),Buffer Pool 中包含了磁盘数据页的映射,可以当做缓存来使用:

    • 读数据:会首先从缓冲池中读取,如果缓冲池中没有,则从磁盘读取在放入缓冲池;
    • 写数据:会首先写入缓冲池,缓冲池中的数据会定期同步到磁盘中;

      我们知道,MySQL表数据是持久化到磁盘中的,但如果所有操作都去操作磁盘,等并发上来了,那处理速度谁都吃不消,因此引入了缓冲池(Buffer Pool)的概念,Buffer Pool 中包含了磁盘中部分数据页的映射,可以当做缓存来用;这样当修改表数据时,我们把操作记录先写到Buffer Pool中,并标记事务已完成,等MySQL空闲时,再把更新操作持久化到磁盘里(你可能会问,到底什么时候执行持久化呢?1、MySQL线程低于高水位;2、当有其他查询、更新语句操作该数据页时),从而大大缓解了MySQL并发压力。

      但是它也带来了新的问题,当MySQL系统宕机,断电时Buffer Pool数据不就丢了?

      因为我们的数据已经提交了,但此时是在缓冲池里头,还没来得及在磁盘持久化,所以我们急需一种机制需要存一下已提交事务的数据,为恢复数据使用。

      于是 redo log + binlog的经典组合就登场了,这里不在扩展赘述。可参考《听我讲完redo log、binlog原理,面试官老脸一红》

    3、隔离性原理

      隔离性是事务ACID特性里最复杂的一个。在SQL标准里定义了四种隔离级别,每一种级别都规定一个事务中的修改,哪些是事务之间可见的,哪些是不可见的。

      级别越低的隔离级别可以执行越高的并发,但同时实现复杂度以及开销也越大。

    搞懂MySQL事务隔离级别请参考《上个厕所的功夫,搞懂MySQL事务隔离级别》

    Mysql 隔离级别有以下四种(级别由低到高):

    隔离级别效果
    读未提交(RU)一个事务还没提交时,它做的变更就能被别的事务看到。(别的事务指同一时间进行的增删改查操作)
    读提交(RC)一个事务提交(commit)之后,它做的变更才会被其他事务看到。
    可重复读(RR)一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。
    当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。
    串行(xíng)化(S)正如物理书上写的,串行是单线路,顾名思义在MySQL中同一时刻只允许单个事务执行,“写”会加“写锁”,“读”会加“读锁”。
    当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

      搞懂了隔离级别以及实现原理其实就可以理解ACID里的隔离性了。前面说过原子性,隔离性,持久性的目的都是为了要做到一致性,但隔离型跟其他两个有所区别,原子性和持久性是为了要实现数据的正确、可用,比如要做到宕机后的恢复、事务的回滚等,保证数据是正确可用的!

      那么隔离性是要做到什么呢?

      隔离性要管理的是:多个并发读写请求(事务)过来时的执行顺序。像交警在马路口儿指挥交通一样,当并发处理多个DML更新操作时,如何让事务操作他该看到的数据,出现多个事务处理同一条数据时,让事务该排队的排队,别插队捣乱,保证数据和事务的相对隔离,这就是隔离性要干的事儿。
    在这里插入图片描述

      一段大白话,听的明明白白的同学们,记得收藏转发一波,或许,你能帮到别人!

      所以,从隔离性的实现原理上,我们可以看出这是一场数据的可靠性与性能之间的权衡。

    4、一致性原理

      一致性,我们要保障的是数据一致性,数据库中的增删改操作,使数据库不断从一个一致性的状态转移到另一个一致性的状态

      事务该回滚的回滚,该提交的提交,提交后该持久化磁盘的持久化磁盘,该写缓冲池的写缓冲池+写日志;对于数据可见性,通过四种隔离级别进行控制,使得库表中的有效数据范围可控,保证业务数据的正确性的前提下,进而提高并发程度,支撑服务高QPS的稳定运行,保证数据的一致性,这就是咱们叨叨叨说的清楚想不明白的数据库ACID四大特性。

    总结

      希望通过本篇文章你熟知并搞懂了我们天天说的数据库ACID四大特性,本文中我们一起串联了起来,相信你不会在忘记某一个,打麻将三缺一怎么行?

      好了,多了就不说了,我劝你耗子尾汁,但推荐你关注我,因为我会让你在快乐中学会很多东西!


    MySQL系列文章汇总与《MySQL江湖路 | 专栏目录》

    往期热门MySQL系列文章

    展开全文
  • MySQL(一)–ACID四大特性以及隔离级别 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity)  原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面...

    MySQL(一)–ACID四大特性以及隔离级别

    如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性:

    ⑴ 原子性(Atomicity)
      原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

    ⑵ 一致性(Consistency)
      一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态

    拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。

    ⑶ 隔离性(Isolation)
    隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离

    即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

    关于事务的隔离性数据库提供了多种隔离级别,稍后会介绍到。

    ⑷ 持久性(Durability)

    持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作

    例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。

    以上介绍完事务的四大特性(简称ACID),现在重点来说明下事务的隔离性,当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题:

    1,脏读:
      脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

    当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下

        update account set money=money+100 where name=’B’;  (此时A通知B)
    
        update account set money=money - 100 where name=’A’;
    

    当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。
      
    怎么解决脏读?

    • ①用隔离级别(设置为repeatable read,可重复读的隔离级别)
    • ②对数据增加版本号(乐观锁)==>读时version不一样,则放弃

    2,不可重复读:
      不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了

    例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

    不可重复读和脏读的区别是脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

    在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了……

    3,虚读(幻读):
      幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

    幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。简答的理解就是:不可重复读是数据变了,幻读是数据的行数变了

    幻读:

    幻读是:一次事物里,多次查询后,结果集的个数不一致情况叫“幻读”。

    mysql是怎样解决幻读的?

    - ①多版本并发控制(mvcc)(快照读/一致性读)。一致性读:是通过mvcc为查询提供一个基于时间点的快照。这个查询只能看到自己之前提交的数据,而在查询开始之后,提交的数据是不可以看到的。

    • next-key锁(当前读)next-key原理当前数据行与上一条数据和下一条数据之间的间隙锁定,保证此范围内读取数据是一致的。next-key锁包括什么?包括记录锁(记录锁是:加在索引上的锁)和间隙锁(加在索引之间的锁)

    现在来看看MySQL数据库为我们提供的四种隔离级别

    Read uncommitted (读未提交)最低级别,任何情况都无法保证。会造成脏读

    Read committed (读已提交或者叫不可重复读):=可避免脏读的发生大多数数据库系统默认的是这个,但是MySQL不是,MySQL默认的是可重复读的级别
    Repeatable read (可重复读)可避免脏读、不可重复读的发生。但是会造成幻读的发生
    Serializable (串行化)可避免脏读、不可重复读、幻读的发生。最好的隔离级别

    隔离性由低到高,并发性由高到底。

    以上四种隔离级别最高的是Serializable级别最低的是Read uncommitted级别,当然级别越高,执行效率就越低。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)。

    在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);而在Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别。

    如何保证事务ACID特性(也就是如何实现的):

    原子性:

    定义:

    原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做。

    如果事务中一个 sql 语句执行失败,则已执行的语句也必须回滚,数据库退回到事务前的状态。

    实现原理:undo log

    在说明原子性原理之前,首先介绍一下 MySQL 的事务日志。MySQL 的日志有很多种,如二进制日志、错误日志、查询日志、慢查询日志等。

    此外 InnoDB 存储引擎还提供了两种事务日志:

    • redo log(重做日志)
    • undo log(回滚日志)

    其中 redo log 用于保证事务持久性;undo log 则是事务原子性和隔离性实现的基础。

    下面说回 undo log。实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的 sql 语句

    • 当事务对数据库进行修改时,InnoDB 会生成对应的 undo log。
    • 如果事务执行失败或调用了 rollback,导致事务需要回滚,便可以利用 undo log 中的信息将数据回滚到修改之前的样子。

    当发生回滚时,InnoDB 会根据 undo log 的内容做与之前相反的工作:

    • 对于每个 insert,回滚时会执行 delete。

    • 对于每个 delete,回滚时会执行 insert。

    • 对于每个 update,回滚时会执行一个相反的 update,把数据改回去。

    生成的 undo log 中会包含被修改行的主键(以便知道修改了哪些行)、修改了哪些列、这些列在修改前后的值等信息,回滚时便可以使用这些信息将数据还原到 update 之前的状态。

    持久性:

    定义:

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

    实现原理:redo log

    下面先聊一下 redo log 存在的背景:

    InnoDB 作为 MySQL 的存储引擎,数据是存放在磁盘中的,但如果每次读写数据都需要磁盘 IO,效率会很低

    为此,InnoDB 提供了缓存(Buffer Pool),Buffer Pool 中包含了磁盘中部分数据页的映射,作为访问数据库的缓冲:

    当从数据库读取数据时,会首先从 Buffer Pool 中读取,如果 Buffer Pool 中没有,则从磁盘读取后放入 Buffer Pool。

    当向数据库写入数据时,会首先写入 Buffer Pool,Buffer Pool 中修改的数据会定期刷新到磁盘中(这一过程称为刷脏)

    Buffer Pool 的使用大大提高了读写数据的效率,但是也带来了新的问题如果 MySQL 宕机,而此时 Buffer Pool 中修改的数据还没有刷新到磁盘,就会导致数据的丢失,事务的持久性无法保证。

    于是,redo log 被引入来解决这个问题当数据修改时,除了修改 Buffer Pool 中的数据,还会在 redo log 记录这次操作;当事务提交时,会调用 fsync 接口对 redo log 进行刷盘

    如果 MySQL 宕机,重启时可以读取 redo log 中的数据,对数据库进行恢复。

    既然 redo log 也需要在事务提交时将日志写入磁盘,为什么它比直接将 Buffer Pool 中修改的数据写入磁盘(即刷脏)要快呢?

    主要有以下两方面的原因

    • 刷脏是随机 IO因为每次修改的数据位置随机,但写 redo log 是追加操作,属于顺序 IO
    • 刷脏是以数据页(Page)为单位的,MySQL 默认页大小是 16KB,一个 Page 上一个小修改都要整页写入;而 redo log中只包含真正需要写入的部分,无效 IO 大大减少

    redo log 与 binlog:

    我们知道,在 MySQL 中还存在 binlog(二进制日志)也可以记录写操作并用于数据的恢复,但二者是有着根本的不同的

    1,作用不同:

    • redo log 是用于 crash recovery 的,保证 MySQL 宕机也不会影响持久性;
    • binlog 是用于 point-in-time recovery 的,保证服务器可以基于时间点恢复数据,此外 binlog还用于主从复制。

    2,层次不同:

    • redo log 是 InnoDB 存储引擎实现的,
    • 而 binlog 是 MySQL 的服务器层(可以参考文章前面对 MySQL 逻辑架构的介绍)实现的,同时支持 InnoDB 和其他存储引擎。

    3,内容不同:

    • redo log 是物理日志,内容基于磁盘的 Page。
    • binlog 是逻辑日志,内容是一条条 sql。

    4,写入时机不同:

    • redo log 的写入时机相对多元。前面曾提到,当事务提交时会调用 fsync 对 redo log进行刷盘;这是默认情况下的策略,修改 innodb_flush_log_at_trx_commit参数可以改变该策略,但事务的持久性将无法保证。

      除了事务提交时,还有其他刷盘时机:如 master thread 每秒刷盘一次 redo log 等,这样的好处是不一定要等到 commit 时刷盘,commit 速度大大加快。

    • binlog 在事务提交时写入。

    隔离性:

    定义:

    与原子性、持久性侧重于研究事务本身不同,隔离性研究的是不同事务之间的相互影响

    隔离性是指事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

    那么隔离性的探讨,主要可以分为两个方面:

    • (一个事务)写操作对(另一个事务)写操作的影响锁机制保证隔离性。
    • (一个事务)写操作对(另一个事务)读操作的影响MVCC 保证隔离性。

    锁机制的基本原理可以概括为

    • 事务在修改数据之前,需要先获得相应的锁。
    • 获得锁之后,事务便可以修改数据。
    • 该事务操作期间,这部分数据是锁定的,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。

    还会涉及到行锁,表锁啥的…

    MVCC: MVCC 全称 Multi-Version Concurrency Control,即多版本的并发控制协议。

    下面的例子很好的体现了 MVCC 的特点在同一时刻,不同的事务读取到的数据可能是不同的(即多版本)——在 T5 时刻,事务 A 和事务 C 可以读取到不同版本的数据。

    在这里插入图片描述
    MVCC 最大的优点是读不加锁,因此读写不冲突,并发性能好。InnoDB 实现 MVCC,多个版本的数据可以共存,主要是依靠数据的隐藏列(也可以称之为标记位)和 undo log

    其中数据的隐藏列包括了该行数据的版本号、删除时间、指向 undo log 的指针等等。

    MVCC的一些相应的解释,可以看看这个文章数据库MVCC 隔离级别

    当读取数据时,MySQL 可以通过隐藏列判断是否需要回滚并找到回滚需要的 undo log,从而实现 MVCC;

    小结:概括来说,InnoDB 实现的 RR,通过锁机制、数据的隐藏列、undo log 和类 next-key lock,实现了一定程度的隔离性,可以满足大多数场景的需要

    一致性:

    定义:

    一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。

    实现:

    可以说,一致性是事务追求的最终目标:前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。此外,除了数据库层面的保障,一致性的实现也需要应用层面进行保障。

    实现一致性的措施包括:

    • 保证原子性、持久性和隔离性,如果这些特性无法保证,事务的一致性也无法保证。
    • 数据库本身提供保障,例如不允许向整形列插入字符串值、字符串长度不能超过列的限制等。
    • 应用层面进行保障,例如如果转账操作只扣除转账者的余额,而没有增加接收者的余额,无论数据库实现的多么完美,也无法保证状态的一致。

    总结:

    下面总结一下 ACID 特性及其实现原理:

    • 原子性:语句要么全执行,要么全不执行,是事务最核心的特性。事务本身就是以原子性来定义的;实现主要基于 undo log。
    • 持久性:保证事务提交后不会因为宕机等原因导致数据丢失;实现主要基于 redo log
    • 隔离性:保证事务执行尽可能不受其他事务影响;InnoDB 默认的隔离级别是 RR(REPEATABLE READ也就是可重复读),RR 的实现主要基于锁机制、数据的隐藏列、undo log 和类 next-key lock 机制
    • 一致性:事务追求的最终目标,一致性的实现既需要数据库层面的保障,也需要应用层面的保障。

    感谢并参考:

    https://blog.csdn.net/qfc8930858/article/details/88530137

    https://blog.csdn.net/enmotech/article/details/86710350

    展开全文
  • 面试官:"知道事务的四大特性么?"你:"懂,ACID嘛,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)!"面试官:“你们是用mysql数据库吧,能简单说说innodb中怎么实现这四大特性的么...

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

    面试官:"知道事务的四大特性么?"你:"懂,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元,依然出现了数据不一致的情形!

    持久性

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

    如果无法保证持久性会怎么样?

    在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来的快。

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

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

    表名t_balance

    深入理解MySQL的ACID四大特性原理

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

    深入理解MySQL的ACID四大特性原理

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

    如果一个事务读取的行正在做DELELE或者UPDATE操作,读取操作不会等行上的锁释放,而是读取该行的快照版本。

    由于MVCC机制在可重复读(Repeateable Read)和读已提交(Read Commited)的MVCC表现形式不同,就不赘述了。

    但是有一点说明一下,在事务隔离级别为读已提交(Read Commited)时,一个事务能够读到另一个事务已经提交的数据,是不满足隔离性的。但是当事务隔离级别为可重复读(Repeateable Read)中,是满足隔离性的。

    总结

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

    转载于:https://www.cnblogs.com/CQqf2019/p/10978983.html

    展开全文
  • 数据库事务的ACID四大特性及脏读,不可重复读,幻读等 事务(transaction)到底是个啥? transaction有事务、交易的含义,翻译成事务,很难理解。如果理解为交易,就很清楚了。 想想如果要完成一笔交易,肯定一手交钱...
  • 数据库的事务必须满足4个特性:原子性, 一致性, 隔离性, 持久性,它们英文单词首字母合起来就是:ACID 在这些事务特性中,数据“一致性”为最终目标,其他特性都是为达到这个目标而采取的措施和手段。数据库...
  • 事务: ...事务的四大特性ACID): 原⼦性: 事务的原⼦性确保动作要么全部完成,要么完全不起作⽤; ⼀致性: 执⾏事务前后,数据保持⼀致,多个事务对同⼀个数据读取的结果是相同的; 隔离性:
  • 事务ACID四大特性 A:原子性(Atomicity) 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。 事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像...
  • ACID事务的四大特性

    2022-03-12 10:17:53
    事务四大特性(简称ACID) 1、原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部完成,要么均不执行。 2、一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果...
  • ACID--事务四大特性

    千次阅读 2022-04-18 19:19:33
    ACID,指的是在数据库事务正确执行的四个基本要素的缩写。 具体解释: 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability) 任何一个数据库事务必须满足ACID,只有这样才能...
  • 一、四大特性ACID) 数据库事务是访问并可能操作各种数据项的一个数据库操作序列 1、原子性Atomicity:事务内包含的所有操作要么全部成功,要么全部失败回滚。实现:日志,将所有的更新操作写入日志中,若因为...
  • 事务的四大特性(ACID)

    千次阅读 2021-10-29 08:50:24
    一.什么是事务 事务(Transaction)是并发控制单位,是用户定义的一个...事务的四大特性ACID) 事务具有四个特征:原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability
  • 事务及ACID四大特性

    2020-01-10 09:23:34
    事务及ACID四大特性 1. 事务 事务(Transaction)是并发控制单位,是用户定义的一个操作序列,这些操作要么都做,要么都不做,是一个不可分割的工作单位。 在计算机术语中是指访问并可能更新数据库中各种数据项的一...
  • Redis-事物&事物的四大特性(ACID)

    千次阅读 2020-01-08 19:57:51
    事物的四大特性:(ACID) 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚 ,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。 ...
  • A 原子性(Atomicity) 就是把事物分割成像原子一样,表示我们事物需要细微的去控制。比如我给你转钱,里面有我扣钱,你到账。总不能我扣了钱,你没到账这种情况吧。所以就是指转账这个事物, 里面的所有环节哪怕一...
  • 数据库事务的四大特性ACID

    万次阅读 2019-06-18 17:10:04
    数据库事务的四大特性 1, 什么是数据库事务? 数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。 意思就是一连串的数据库操作,即一串增删查改的集合。 2, 数据库事务做了什么? ...
  • 转自:https://blog.csdn.net/xmh594603296/article/details/79676844 数据库ACID四大特性及脏读,不可重复读,幻读,事物丢失 A 原子性(Atomicity) [ˌædəˈmɪsədi] 就是把事物分割成像原子一样,表示我们...
  • 事务的四大特性ACID

    万次阅读 2019-12-20 14:27:24
    相关历史文章(阅读本文之前,您可能需要先看下之前的系列????) ... 事务的四大特性主要是:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。 一...
  • 原子性 原子性是指一个事务是一个不可分割的工作状态,其中的操作要么都做,要么都不做 一致性 一致性是指事务执行前后,数据处于一种...也就是说ACID四大特性之中,一致性是目的,原子性、隔离性、持久性是手段,
  • **也就是说ACID四大特性之中,一致性是目的,原子性、隔离性、持久性是手段,是为了保持一致性,数据库提供的手段。只有数据库实现了AID三大特性,才有可能实现一致性从应用层面来说,通过代码判断数据库是否有效...
  • 事务四大特性ACID

    2019-08-16 22:50:22
    在介绍前先说一下主要实现的功能介绍使用: 在我们使用update,delete,insert 执行完MYSQL数据库会自动提交,操作磁盘数据库储存到磁盘中,在个体语句执行的时候是各自独立的,对信息的删除,修改和添加的时候这就...
  • 事务的原子性(Atomicity) 是指一个事务要么全部执行,要么全部不执行,不能执行到一般就不执行了。 例如A向B转账100元,A-100 和B+100 这两个操作要么都执行,要么都不执行,不然会导致严重的数据错误 ...
  • ACID(事务四大特性

    千次阅读 多人点赞 2019-08-15 17:55:25
    事务四大特性ACID): 原子性(Atomicity):化学中的原子指不可再分的基本微粒,数据库中原子性强调事务是一个不可分割的整体,事务开始后所有操作要么全部成功,要么全部失败,不可能停滞在中间某个环节。如果...
  • 1、原子性(Atomicity) 原子性是指一个事物内所有操作共同组成一个原子包,要么全部成功,要么全部失败回滚。也就是说事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。...
  • 数据库事务的ACID四大特性以及MySQL中的隔离级别 事务是一个单独的逻辑工作单元,事务中的所有更新操作要么都执行,要么都不执行。事务保证了一系列更新操作的原子性。如果事务之间存在并发操作,则可以通过食物...
  • ⑴ 原子性(Atomicity)  原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的 操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。 ⑵ 一致性(Consistency) ...
  • 数据库ACID特性 原子性:整个事务中的操作,要么全部完成,要么全部不完成。 一致性:事务可以封装状态改变,无论并发操作有多少,数据库的完整性不会被破坏。 隔绝性:多个事务并发访问时,事务间是隔绝的。 持久...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,961
精华内容 4,784
关键字:

acid四大特性

友情链接: jisuanqi.zip