版权声明:本文为 小异常 原创文章,非商用自由转载-保持署名-注明出处,谢谢!
本文网址:https://blog.csdn.net/sun8112133/article/details/89173479

文章目录

  • 一、幻读概述
    • 1、事例
    • 2、分析
  • 二、演示幻读
    • 1、新建一个数据库(bank库),并准备一张表(account表)
    • 2、打开两个窗口,并分别设置自动提交方式为off
    • 3、将A窗口的隔离级别设置成 “读已提交”
    • 4、两个窗口分别开启事务
    • 5、在B窗口新增一条数据,并提交事务
    • 6、分别在数据库和A窗口中查看数据
  • 三、不可重复读和幻读的区别

在事务的并发操作中,也就是多个事务同时对同一组数据进行操作时,可能会出现脏读、不可重复读、幻读、丢失更新这四个问题,本篇博客就来为大家讲解 幻读 问题。

一、幻读概述

幻读 就是一个事务读到另一个事务新增加并提交的数据(insert)。在同一个事务中,对于同一组数据读取到的结果不一致。比如,事务A 新增了一条记录,事务B 在 事务A 提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。幻读出现的原因就是由于事务并发新增记录而导致的。
 
隔离级别 有四种,分别是:读未提交、读已提交、可重复读、序列化。
  读未提交: Read Uncommitted,顾名思义,就是一个事务可以读取另一个未提交事务的数据。最低级别,它存在4个常见问题(脏读、不可重复读、幻读、丢失更新)。
  读已提交: Read Committed,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。 它解决了脏读问题,存在3个常见问题(不可重复读、幻读、丢失更新)。
  可重复读: Repeatable Read,就是在开始读取数据(事务开启)时,不再允许修改操作 。它解决了脏读和不可重复读,还存在2个常见问题(幻读、丢失更新)。
  序列化: Serializable,序列化,或串行化。就是将每个事务按一定的顺序去执行,它将隔离问题全部解决,但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
 
大多数数据库默认的事务隔离级别是 Read Committed,比如 SQL Server , Oracle。但 MySQL 的默认隔离级别是 Repeatable Read。

1、事例

程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(妻子事务开启),看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现有两条记录,共花了1.2万元,似乎出现了幻觉,这就是幻读。

2、分析

在这个事例中,事务B读取了数据,接着另一个事务A插入了一条数据。在随后的查询中,事务B就会发现多了一条原本不存在的记录,就好像发生了幻觉一样,这是由于数据新增导致的。


二、演示幻读

1、新建一个数据库(bank库),并准备一张表(account表)

2、打开两个窗口,并分别设置自动提交方式为off

show variables like 'autocommit';   – 查看当前的自动提交是否开启

set autocommit = off;   – 将自动提交关闭

3、将A窗口的隔离级别设置成 “读已提交”

注意: 虽然 “可重复读” 这种隔离级别也会发生“幻读”这个问题,但是如果设置成这种隔离级别是演示不出效果的,因为只有在多个事务并发了,才可能出现 “幻读” 问题了,但是大家要记住“可重复读”这种隔离级别也是有可能会出现“幻读”的。

select @@tx_isolation;   – 查询当前的隔离级别

set session transaction isolation level read committed;   – 设置当前会话隔离级别为“读已提交”

4、两个窗口分别开启事务

start transaction;   – 开启事务 或 begin; 也可以显式开启事务

5、在B窗口新增一条数据,并提交事务

use bank   – 切换到bank数据库

insert into account values(null, 'wangwu', 1000);   – 增加一条数据

commit;   – 提交事务

6、分别在数据库和A窗口中查看数据

select * from account;    – 查看account中的全部数据

这种效果和 不可重复读 的效果是一样的。数据库和A窗口中的数据都发生了改变,因为B窗口已经提交了事务,所以数据库中的数据发生改变,是属于正常现象。但是这种事务的隔离性似乎不是太好(事务的隔离性是一个事务的执行,不受其他事务的干扰),你看,B窗口提交了事务,影响到了A窗口中数据,这种隔离级别虽然解决了 ”脏读“ 问题,但是还会引发 “不可重复读”、“幻读”及“丢失更新” 问题。

三、不可重复读和幻读的区别

不可重复读的重点是修改数据,幻读的重点是新增或者删除记录。

不可重复读,改变的是数据,数据记录总条数并没有发生改变;
幻读,改变的是数据记录总条数,原来数据的值,没有发生改变,只是新增了记录条数。

疑问:
大家可能会有这样的疑问,幻读不是因为第二次读到的结果和第一次读到的结果不一样而产生幻觉,所以叫幻读嘛?好像不可重复读也是这样的,那为什么不可重复读不叫幻读呢?那是因为大家可能忽略了一个细节,不可重复读改变的是同一条数据,而幻读改变的是数据的条数。第一次读到一条,第二次却读到了两条,好像产生了幻觉一样,所以叫幻读;而不可重复读是第一次读到这个数据的值和第二次读到这个数据的值不一样,也就是相同的数据不能重复读两次,否则会出错,所以它叫做不可重复读。

有关事务的知识可以参考我之前写的博客《【Spring4.0笔记整理十七】Spring事务详解》 及 【Spring4.0笔记整理十八】Spring事务管理详解 。

博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!

MySQL事务之幻读问题相关推荐

  1. MySQL事务的幻读

    幻读--PHANTON READ 又称为虚度,是指在一个事务内,两次查询中数据条数不一致 幻读和不可重复读类似,都是在两次查询过程中,区别,幻读是由于其他事务做了插入记录的操作,导致,记录条数有所增加 ...

  2. mysql 什么是幻读_Mysql中的幻读(一)

    什么是幻读 幻读表示的是在一个事物里面 同一个select语句,前后两次查询出来的结果是不相同的,需要注意的一点是,在InnoDB里面,幻读跟事物的隔离级别有关,更加准确的说是跟一个事物的快照和当前读 ...

  3. mySql 脏读,幻读,不可重复度与事务隔离级别

    mysql有3种并发问题 脏读 读到未提交的数据 A事务 B事务 开启事务 查询结果100 开启事务 更新到150,未提交 查询结果150 回滚 查询结果100 A事务查询到了B事务未提交的内容.这种 ...

  4. mysql事务的重复性读_Mysql下InnoDB的可重复读级别的事务测试

    Mysql下InnoDB的可重复读的事务测试 ### 背景: * mysql版本:Server version: 5.1.71 * 操作系统:CentOS 6.5 X64 * 事务隔离级别:不可重复读 ...

  5. mysql实战20 | 幻读是什么,幻读有什么问题?

    在上一篇文章最后,我给你留了一个关于加锁规则的问题.今天,我们就从这个问题说起吧. 为了便于说明问题,这一篇文章,我们就先使用一个小一点儿的表.建表和初始化语句如下(为了便于本期的例子说明,我把上篇文 ...

  6. MySQL 事务隔离级别,读现象,MVCC

    目录 数据库读现象. 事务隔离级别 错误日志 详情参见:MySQL日志管理 - JasonJi - 博客园 mvcc多版本并发控制 多版本并发控制mvcc(multi-version concurre ...

  7. mysql脏读,幻读,不可重复读以及间隙所解决幻读

    1.数据脏读 事务a修改了某条数据,然后事务b读取了事务a修改的该条数据,然后事务a由于某些原因,事务a回滚了,这样事务b读到的数据就和回滚的数据不同了,这时事务b读取的数据就是脏数据.概况一句话就是 ...

  8. mysql java 解决幻读_MySQL 是如何解决幻读的

    MySQL 是如何解决幻读的 一.什么是幻读 在一次事务里面,多次查询之后,结果集的个数不一致的情况叫做幻读. 而多出来或者少的哪一行被叫做 幻行 二.为什么要解决幻读 在高并发数据库系统中,需要保证 ...

  9. mysql 什么是幻读_何为幻读?MySQL又是如何解决幻读的?

    一.什么是幻读 在一次事务里面,多次查询之后,查询的结果集的个数不一致的情况叫做幻读.而多出来或者少的哪一行被叫做 幻行 二.为什么要解决幻读 在高并发数据库系统中,需要保证事务与事务之间的隔离性,还 ...

  10. mysql rr解决幻读吗_mysql rr隔离级别解决幻读了吗

    以下内容全部基于innodb. 虽然下面有很多概念很浅显,但还是要解释一下 什么是幻读? 当一个事务在多次查询中,发现了一行不是在当前事务中添加的数据.出现这种问题就叫做幻读. 关于四种隔离级别 未提 ...

最新文章

  1. 毕业使人头秃:发现自己的idea已经被人发表了,该怎么办?
  2. 大量linux内存被cached
  3. Android性能测试-分析工具
  4. 四十一、Android Notification通知详解
  5. 2019年1月已到,Java 8 要收费了吗?
  6. 删除VS.NET起始页上项目名称的方法.
  7. 移通好闹钟微信小程序全套源码
  8. 有哪些类目适合刚创业的新手淘宝卖家做?
  9. C#高级编程9 第18章 部署
  10. php的Allowed memory size of 134217728 bytes exhausted问题解决办法
  11. bcp 不能调用where 子句_三、p18-28条件查询、分组聚合、排序where/group by/having/order by...
  12. eltable表头高度无法设置_厨房吊顶高度一般多少?厨房吊顶安装需要注意什?...
  13. noip2013 day1
  14. STM32示波器设计
  15. 批处理For--分割字符串
  16. 多数据源的配置,详细(新手,错误之处,请指正)
  17. 新手怎样利用博客推广
  18. 处理服务器恶意程序 kthreaddi挖矿
  19. 计算机主机解剖图,电脑主机结构示意图
  20. c++initgraph函数_二次函数图像绕其顶点旋转180°后所得图像的解析式

热门文章

  1. Mybatis游标Cursor查询
  2. 通俗易懂的讲解 网关是什么
  3. vs code默认浏览器
  4. [完]PHP 格式化显示时间 date() 函数
  5. 富文本编辑器ueditor——找不到ueditor.all.js以及ueditor.all.min.js文件
  6. markdown基础
  7. 区块链网络管理平台WeBASE双节点可视化部署
  8. PostScript语言里的珠玑
  9. 计算机安装win10系统还原,解决win10电脑一键还原教程
  10. java io closed_java.io.IOException: Stream closed 异常的原因和处理