别再误解mysql的幻读了_innodb如何解决幻读

别再误解mysql的幻读了_innodb如何解决幻读MySQL InnoDB引擎在Repeatable Read(可重复读)隔离级别下,到底有没有解决幻读的问题?
网上众说纷纭,有的说解决了,有的说没解决,甚至有些大v的意见都无法达成统一。
今天就深入

MySQL到底有没有解决幻读问题?这篇文章彻底给你解答

MySQL InnoDB引擎在Repeatable Read(可重复读)隔离级别下,到底有没有解决幻读的问题?

网上众说纷纭,有的说解决了,有的说没解决,甚至有些大v的意见都无法达成统一。

今天就深入剖析一下,彻底解决这个幻读的问题。

解决幻读问题之前,先普及几个知识点。

1. 并发事务产生的问题

先创建一张用户表,用作数据验证:

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT "主键",
  `name` varchar(100) DEFAULT NULL COMMENT "姓名",
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT="用户表";

并发事务会产生下面三个问题:

脏读

定义: 一个事务读到其他事务未提交的数据。

image

从上面的示例图中,可以看出,在事务2修改完数据,没有提交的情况。事务1已经读到事务2最新修改的数据,这种情况就属于脏读。

不可重复读

定义: 一个事务读取到其他事务修改过的数据。

image

从上面的示例图中,可以看出,在事务2修改完数据,并提交事务后。事务1第二次查询已经读到事务2最新修改的数据,这种情况就属于不可重复读。

幻读

定义: 一个事务读取到其他事务最新插入的数据。

image

从上面的示例图中,可以看出,在事务2插入完数据,并提交事务后。事务1第二次查询已经读到事务2最新插入的数据,这种情况就属于幻读。

2. 快照读和当前读

再普及一下快照读和当前读。

快照读: 读取数据的历史版本,不对数据加锁。

例如:select

当前读: 读取数据的最新版本,并对数据进行加锁。

例如:insert、update、delete、select for update、select lock in share mode。

3. 再谈幻读问题

MySQL在Repeatable Read(可重复读)隔离级别下,到底有没有解决幻读的问题?

只能说是部分解决了幻读问题。

首先,在快照读的情况下,是通过MVCC(复用读视图)解决了幻读问题。

想详细了解MVCC和读视图,可以翻一下上篇文章。

先手动设置一下MySQL的隔离级别为可重复读

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

image

执行测试用例,验证一下:

image

从上面的示例图中,可以看出,事务1的两次查询,得到的结果一致,并没有查到事务2最新插入的数据。

原因是,在可重复读隔离级别下,第一次快照读的时候,生成了一个读视图。第二次快照读的时候,复用了第一次生成的读视图,所以两次查询得到的结果一致。

所以,在快照读的情况下,可重复读隔离级别是解决了幻读的问题。

再测试一下,在当前读的情况下,可重复读隔离级别是否解决幻读问题:

image

从上面的示例图中,可以看出,事务1的两次查询,得到的结果不一致。在事务2插入数据,并提交事务后。事务1的第二次执行当前读(加了for update)的时候,读到了事务2最新插入的数据。

原因是,在可重复读隔离级别下,每次执行当前读会生成一个新的读视图,所以能读到其他事务最新插入的数据。

所以,在当前读的情况下,可重复读隔离级别是没有解决了幻读的问题。

在执行上面的测试用例的时候,我忽然想到一个问题,既然select for update的当前读,出现了幻读问题,是不是其他的当前读也会复现幻读问题,比如insert。

再执行测试用例,验证一下:

image

跟预想的一样,在insert当前读的情况下,也出现了幻读的问题(主键冲突)。

那有没有什么办法?在可重复读隔离级别下,执行当前读的时候,也能解决幻读的问题?

当然有的,唯一的办法就是加锁

image

事务1在执行第一次查询的时候,就对数据进行加锁(使用for update),防止其他事务修改数据,这样也就彻底解决了幻读问题。

你觉得有什么好办法吗?

image

原文地址:https://www.cnblogs.com/yidengjiagou/archive/2022/09/13/16688967.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/4779.html

(0)
上一篇 2023-06-05
下一篇 2023-06-05

相关推荐

  • MySQL8.0-练习制作大学生手游情况调查系统1「终于解决」

    MySQL8.0-练习制作大学生手游情况调查系统1「终于解决」步骤: 1、以管理员身份运行dos窗口,开启MySQL服务,指令:net start MySQL80 2、以管理员身份运行MySQL 3、创建一个数据库,指令:create database data

    2023-04-23
    140
  • Python字符串添加字符串

    Python字符串添加字符串Python中,字符串是不可变的,也就是说,一旦一个字符串被创建,它不能被修改。那么如果我们需要在一个字符串的某个位置添加另一个字符串,应该怎么实现呢?本篇文章将详细讲解Python中字符串添加字符串的方法。

    2024-08-02
    35
  • python中验证ip正则(正则验证ip地址)

    python中验证ip正则(正则验证ip地址)首先给出一个c函数的原型:int sscanf(const char *buffer,const char *format,[argument ]…)它的返回值是参数的数据,也就是argument的个数,buffer:存储的数据,format:格式控制字符串,argument:选择性设定字符串。这个程序从标准流读取数据,可以进行无限制的输入。下面贴出代码,然后引出另外一个问题,将字符串ip转换成整形ip地址。[cpp]

    2023-11-19
    138
  • 使用bs4.select解析网页中的标题元素

    使用bs4.select解析网页中的标题元素在网络爬取和数据分析中,常常需要使用Python对网页进行解析,获取网页中所需的数据和信息。其中,使用bs4库中的select方法来解析网页中的标题元素h1/h1,生成一个纯净、简洁的标题是一个很常见的需求。本文将从不同角度介绍使用bs4.select解析网页中的标题元素的技巧与方法。

    2024-07-19
    40
  • 用Python的替换字符串功能将文本格式化

    用Python的替换字符串功能将文本格式化字符串替换功能是指将文本中某个字符或某个字符串替换为另一个字符或字符串的功能。在Python中,我们可以使用内置的字符串方法进行字符串替换操作,即使用replace()方法。

    2024-03-16
    80
  • [20200129]子光标不共享BIND_EQUIV_FAILURE.txt[通俗易懂]

    [20200129]子光标不共享BIND_EQUIV_FAILURE.txt[通俗易懂][20200129]子光标不共享BIND_EQUIV_FAILURE.txt–//生产系统再次遇到大量BIND_EQUIV_FAILURE原因导致子光标的情况。我看了我以前测试遇到的情况。–//链

    2023-01-25
    127
  • 关于代码混淆,你不得不知道的几大基础知识

    关于代码混淆,你不得不知道的几大基础知识移动应用代码安全非常重要,代码逆向会导致代码逻辑被获取,进一步导致控制流被hook,安全防线被破,给APP安全带来巨大风险,因此开发者一般都会进

    2022-12-14
    156
  • 七个生产案例告诉你BATJ为何选择ElasticSearch!应用场景和优势![通俗易懂]

    七个生产案例告诉你BATJ为何选择ElasticSearch!应用场景和优势![通俗易懂]本文来源于公众号【胖滚猪学编程】,转载请注明出处。 从今天开始,想和你一起死磕ElasticSearch,学习分布式搜索引擎,跟着胖滚猪就对了! 既然是ES的第一课,那么最重要的是让你爱上它!不想说那

    2023-03-06
    148

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注