ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

这可能是对MySQL事务讲的最透彻的文章了

2021-03-01 18:29:41  阅读:152  来源: 互联网

标签:事务 20 age 查询 透彻 提交 MySQL 操作


在这里插入图片描述

1. 什么是ACID

  • 原子性(Atomicity): 事务是最小的执行单位,不允许分隔。事务的原子性确保动作要么全部完成,要么完全不起作用
  • 一致性(Consistency): 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的
  • 隔离性(Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,个并发事务之间数据库是独立的
  • 持久性(Durability): 一个事务被提交之后,它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响

2. 并发造成的问题

2.1. 脏读

场景:两个操作同时到达数据库,操作A为查询数据X的age;操作B为更新数据X的age

完全符合ACID的情况下:

这种情况下,操作A和操作B的事务是串行化的,要么先执行操作A,要么先执行操作B,事务没有交叉,一切正常。


并发情况下:

当操作B的事务对数据X进行了修改,但事务还没有提交的同时,操作A开始查询数据X,得到查询结果后,操作B的事务完成了提交。此时,事务B查询的数据是过时的,这种情况就叫做脏读

2.2. 丢失修改

场景: 操作A和操作B同时查询{id=1,age=20}的数据X,并对age进行+1操作

完全符合ACID的情况下:

  1. 第一步:操作A的事务查询到数据X.age=20,进行更新X.age = age + 1 = 21,事务结束。
  2. 第二步:操作A的事务结束后,启动操作B的事务,查询到数据X.age=21,进行更新X.age = age + 1 = 22,事务结束。
  3. 最终结果,X.age=22

并发情况下:

  1. 操作A的事务查询X.age=20,进行更新X.age = age + 1 = 21,此时事务还没有提交;
  2. 操作B在事务A没有提交的情况下,查询X.age=20,进行更新X.age = age + 1 = 21,提交事务X.age=21
  3. 操作A的事务提交,X.age=21
  4. 最终结果X.age=21

后提交的事务将先提交的事务覆盖,这种情况就是丢失修改

2.3. 不可重复读

场景:操作A同一次事务内执行两次uid=1的用户年龄,原始数据age=18;操作B更新uid=1的age=20

完全符合ACID的情况下:

  1. 操作A的事务内,连续执行两次查询,此时其它事务不允许开始,所以在此事务内不管查询多少次uid=1的age都为18,事务提交后
  2. 此时事务A提交,启动操作B事务,更新uid=1的age=20,提交事务。
  3. 操作A查询到的age=18是固定的,为正常结果

并发情况下:

  1. 操作A事务内,第一次查询age=18,此时操作B并发执行
  2. 操作B更新age=20,在操作A事务未进行第二次查询时,操作B事务提交
  3. 操作A此时进行事务内的第二次查询,age=20
  4. 同一个事务内两次查询结果不同,这种情况叫不可重复读

2.4. 幻读

场景:操作A同一个事务内两次查询age < 20的所有用户,比如为20条信息;操作B新增条用户信息,且用户age < 20

完全符合ACID的情况下:

  1. 操作A事务未提交前,其它事务不允许执行,所以此操作内的每次查询都为20条结果
  2. 操作A事务提交后,操作B执行
  3. 两次操作事务串行,操作结果正常

并发情况下:

  1. 操作A事务开启,第一次查询结果为20条
  2. 在操作A未进行第二次查询时,操作B事务开启,插入一条用户age<20的数据,提交事务
  3. 操作A进行第二次查询,结果为21条
  4. 此时,两次查询结果的数量不一致,好像出现了幻觉。我们把这种多次查询数据增多或减少的情况称为幻读

2.5. 脏读和不可重复的区别

这两种情况十分类似,可以这样理解:

  • 脏读: 在一次事务内,只进行一次查询,查询时数据发生了改变,此事务不知道它查询的数据已经发生了变化,这种叫脏读
  • 不可重复读: 在一次事务内,进行多次查询的过程中,此事务知道查询的数据有变化,这种叫不可重复读

主要区别就在于是一次查询,还是多次查询

3. MySQL的隔离级别

  • READ-UNCOMMITTED(读取未提交): 最低隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读、不可重复读
  • READ-COMMITTED(读取已提交): 允许读取并发事务已提交的数据,可以阻止脏读,但是幻读、不可重复读仍有可能发生
    • 两个事务,其中一个事务没有提交的话,另一个事务是没办法读取的,所以可以避免脏读
    • 两个事务,事务A中,第一次读取多条信息时,事务B还没有提交;事务B提交后,事务A进行了第二次查询,可能会查询到事务B提交的数据;如果事务B是插入操作,则是幻读;如果事务B是更新操作,则是不可重复读
  • REPEATABLE-READ(可重复读): 对同一个字段多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍可能发生
    • 两个事务,事务A中,第一次查询到多条数据,事务B可以是插入或更新;如果事务B是更新,由于数据不是被本身事务修改的,所以不会有脏读和不可重复读;如果事务B是插入,仍会被事务A查询到,造成幻读
  • SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有事务串行化依次执行,事务之间完全不可能产生干扰,该级别可以防止脏读、不可重复读和幻读。

4. 最后

面试官: 请讲一下MySQL的事务

标签:事务,20,age,查询,透彻,提交,MySQL,操作
来源: https://blog.csdn.net/weixin_38403680/article/details/114268805

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有