不可重复读与幻读比较相似,都是在一个事务中多次读取到不同的数据。网络上的总结如下

不可重复读:所谓的虚读,也就是大家经常说的不可重复读,是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。比如事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便得到了不同的结果。

一种更易理解的说法是:在一个事务内,多次读同一个数据。在这个事务还没有结束时,另 一个事务也访问该同一数据。那么,在第一个事务的两次读数据之间。由于第二个事务的修改,那么第一个事务读到的数据可能不一样,这样就发生了在一个事务内 两次读到的数据是不一样的,因此称为不可重复读,即原始读取不可重复。

所谓幻读,是指事务A读取与搜索条件相匹配的若干行。事务B以插入或删除行等方式来修改事务A的结果集,然后再提交。
幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也 修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一 样.一般解决幻读的方法是增加范围锁RangeS,锁定检锁范围为只读,这样就避免了幻读。简单来说,幻读是由插入或者删除引起的。

大致的区别在于不可重复读是由于另一个事务对数据的更改所造成的,而幻读是由于另一个事务插入或删除引起的。验证如下:

设置全局与线程隔离级别为read commit,并设置事务手动提交:

mysql> set global transaction isolation level read committed;

Query OK, 0 rows affected (0.00 sec)

mysql> set session transaction isolation level read committed;

Query OK, 0 rows affected (0.00 sec)

mysql> select @@tx_isolation;

+----------------+

| @@tx_isolation |

+----------------+

| READ-COMMITTED |

+----------------+

1 row in set (0.00 sec)

mysql> set global autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like '%auto%';

+-----------------------------+-------+

| Variable_name               | Value |

+-----------------------------+-------+

| auto_increment_increment    | 1     |

| auto_increment_offset       | 1     |

| autocommit                  | OFF   |

| automatic_sp_privileges     | ON    |

| innodb_autoextend_increment | 64    |

| innodb_autoinc_lock_mode    | 1     |

| innodb_stats_auto_recalc    | ON    |

| sql_auto_is_null            | OFF   |

+-----------------------------+-------+

8 rows in set (0.00 sec)

开始事务:t1                             事务t2

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

|  4 | d    |

+----+------+

4 rows in set (0.01 sec)

mysql> use tpcc

Database changed

mysql> update test1 set name='e' where id=4;

Query OK, 1 row affected (0.03 sec)

Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from test1;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

|  4 | d    |

+----+------+

4 rows in set (0.00 sec)

未发生脏读

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

|  4 | e    |

+----+------+

4 rows in set (0.00 sec)

不可重复读发生

mysql> insert into test1(name) values ('f');

Query OK, 1 row affected (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.01 sec)

mysql> select * from test1;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

|  4 | e    |

|  5 | f    |

+----+------+

5 rows in set (0.00 sec)

幻读发生

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

结束事务,释放锁。

可发现在read committed模式下存在不可重复读与幻读。t1、t2事务对test1加共享锁,均可以修改数据但是在commit后生效。

修改事务隔离级别为repeatable read:

mysql> set session transaction isolation level repeatable read;

Query OK, 0 rows affected (0.00 sec)

mysql> set global transaction isolation level repeatable read;

Query OK, 0 rows affected (0.00 sec)

T1 T2

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select name from test1 where id =4;

+------+

| name |

+------+

| d    |

+------+

1 row in set (0.00 sec)

mysql> update test1 set name='f' where id=4;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

mysql> select name from test1 where id =4;

+------+

| name |

+------+

| d    |

+------+

1 row in set (0.00 sec)

未发生脏读

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

成功提交

mysql> select name from test1 where id =4;

+------+

| name |

+------+

| d    |

+------+

1 row in set (0.00 sec)

未发生不可重复读

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

事务提交,释放表锁

mysql> select name from test1 where id =4;

+------+

| name |

+------+

| f    |

+------+

1 row in set (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

数据变化

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

|  4 | f    |

|  5 | f    |

+----+------+

5 rows in set (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into test1(name)values('g');

Query OK, 1 row affected (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1 where id=6;

+----+------+

| id | name |

+----+------+

|  6 | g    |

+----+------+

1 row in set (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from test1;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

|  4 | f    |

|  5 | f    |

+----+------+

5 rows in set (0.00 sec)

mysql> select count(*) from test1;

+----------+

| count(*) |

+----------+

|        5 |

+----------+

1 row in set (0.00 sec)

mysql> select * from test1 where id=6;

Empty set (0.00 sec)

因垂斯汀!!!幻读不见了

后来了解到是因为GAP锁的存在解决了幻读。

幻读与不可重复读区别相关推荐

  1. MYSQL专题: 脏读、幻读、不可重复读区别及解决方案

    并发场景下事务会存在那些数据问题? 并发场景下mysql会出现脏读.幻读.不可重复读问题: 1. 脏读 dirty read(读到未提交的数据): A事务正在修改数据但未提交,此时B事务去读取此条数据 ...

  2. mysql幻读和不可重复读的区别_面试官:MySQL的可重复读级别能解决幻读吗

    Java面试笔试面经.Java技术每天学习一点 Java面试 关注不迷路 作者:宁愿. 来源:https://juejin.im/post/5c9040e95188252d92095a9e 引言 之前 ...

  3. mysql 幻读和不可重复读_幻读和不可重复读的区别

    MySQl MySql默认的隔离级别为Repeatable Read,因此只会出现幻读的情况. 幻读 事务在插入已经检查过不存在的记录时,惊奇的发现这些数据已经存在了,之前的检测获取到的数据如同鬼影一 ...

  4. MySQL 幻读和不可重复读的区别

    背景 最近在学习 MySQL 的事务,幻读和不可重复读很容易搞混.故做此记录总结.先给出两者的定义. 不可重复读 如果一个事务修改了另一个未提交事务读取的数据,就意味着发生了不可重复读现象. r1[x ...

  5. mysql不可重复读和重复读_脏读、幻读、不可重复读的区别是什么

    脏读.幻读.不可重复读的区别:1.脏读就是指当一个事务正在访问数据,并且对数据进行了修改:2.不可重复读是指在一个事务内,多次读同一数据:3.幻读是指当事务不是独立执行时发生的一种现象. [相关学习推 ...

  6. 脏读、幻读、不可重复读,傻傻分不清楚

    脏读 (针对未提交数据) 脏读又称无效数据读出(读出了脏数据).一个事务读取另外一个事务还没有提交的数据叫脏读. 例如:事务T1修改了某个表中的一行数据,但是还没有提交,这时候事务T2读取了被事务T1 ...

  7. 数据库难点:脏读、幻读、不可重复读与四种隔离级别

    目录 前言 一.什么是事务? 二.事务的ACID特性 (1)原子性 (2)一致性 (3)隔离性 (4)持久性 三.何为脏读,幻读,不可重复读? 四.四种隔离级别 前言 本章着重点是介绍:出现脏读.幻读 ...

  8. 17@MySQL数据库读现象详解(脏读、幻读、不可重复读)

    文章目录 MySQL数据库读现象 一.数据库的读现象 1.脏读(dirty read):读取未提交数据 [案列详解] 2.不可重复读取 (nonrepeatable read):前后多次读取,数据内容 ...

  9. mysql可重复读_到底什么是mysql的幻读和不可重复读

    幻读和不可重复读的定义 事务A 按照一定条件进行数据读取, 期间事务B 插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B 新插入的数据称为幻读. 如果事务A 按一定条件搜索, ...

最新文章

  1. JS原生选项卡 – 幻灯片效果
  2. P1203 [USACO1.1]坏掉的项链Broken Necklace
  3. 大数据分析之Hadoop
  4. 利用bladex+avue实现一对多的关系
  5. 高级SmartGWT教程,第1部分
  6. 三分法解决凸(凹)函数极值问题
  7. Apache Phoenix学习记录(SQL on HBase)
  8. 常用Android模拟器的默认监听端口(转载)
  9. 11001-软件架构设计风格及visio使用
  10. HTTP常见错误码原因及解决方法
  11. mysql front的使用注意要点
  12. 浏览器默认主页被篡改(chrome,IE)
  13. 通过企业微信或者微信公众号发送小程序消息推送功能
  14. fx3g485通讯模块_三菱模块FX3U-485ADP-MB MODBUS通信模块
  15. JS将任意格式的时间转为Date对象
  16. sm4加密和sm3加密
  17. 网络安全和黑客技能:15本必读书籍推荐
  18. MySQL查看表结构及查看建表语句
  19. 尝到“线下”的甜,但随行付也吃到了模式的苦
  20. 云呐|机房监控服务平台,机房监控服务平台有哪些

热门文章

  1. mysql教程 check_Check
  2. 基于百度云主机的USDP 2.x 安装详细教程
  3. 左方之地 - 结论 - 组合计数
  4. [LeetCode]179.Largest Number
  5. CSS3 盒子设置border和padding不撑开盒子
  6. 计算机毕业设计Java智能超市导购系统(源码+系统+mysql数据库+lw文档)
  7. ehvierwer登录与不登录_【虎嗅早报】抖音回应无法用微信账号登录:不清楚是否为人为...
  8. 吴恩达DeepLearning第四部分作业week2 基于keras搭建CNNResnet50
  9. java/php/net/python“最终幻想14”游戏时装图鉴网站设计与制作
  10. freessl.cn ssl申请及windows安装