数据库
首页 > 数据库> > 这可能是对MySQL事务讲的最透彻的文章了

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

作者:互联网

在这里插入图片描述

1. 什么是ACID

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的隔离级别

4. 最后

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

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