返回顶部
首页 > 资讯 > 数据库 >详解MySQL幻读及如何消除
  • 463
分享到

详解MySQL幻读及如何消除

2024-04-02 19:04:59 463人浏览 泡泡鱼
摘要

目录事务隔离级别 什么是幻读 如何消除幻读 总结 这是一篇数据库隔离级别的科普文章,旨在了解数据库中著名的幻读现象,为了专注,对脏读、不可重复读不作讨论。 事务隔离级别 Mysql

这是一篇数据库隔离级别的科普文章,旨在了解数据库中著名的幻读现象,为了专注,对脏读、不可重复读不作讨论。

事务隔离级别

Mysql有四级事务隔离级别:

读未提交 READ-UNCOMMITTED: 存在脏读,不可重复读,幻读的问题
读已提交 READ-COMMITTED:不存在脏读,但存在不可重复读,幻读问题
可重复读 REPEATABLE-READ:不存在脏读,不可重复读问题,但存在幻读问题
序列化SERIALIZABLE:解决脏读,不可重复读,幻读问题,但完全串行执行,性能最低

什么是幻读

幻读错误的理解:说幻读是事务A 执行两次 select 操作得到不同的数据集,即 select 1 得到10条记录,select 2 得到11条记录。这其实并不是幻读,这是不可重复读的一种,只会在 R-U R-C 级别下出现,而在 mysql 默认的 RR 隔离级别是不会出现的。

这里给出我对幻读的理解:

幻读,并不是说事务中多次读取获取的结果集不同,幻读更重要的是某次的 select 操作得到的结果集所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 记录不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,如同产生了幻觉

举个例子可能会简化理解:


mysql> show create table user\G
*************************** 1. row ***************************
 Table: user
Create Table: CREATE TABLE `user` (
 `id` int(11) NOT NULL,
 `name` varchar(32) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

分别开启两个事务T1 & T2,并设置其隔离级别为Reaptable-Read:

T1:


mysql> set global transaction isolation level repeatable read;      
​
mysql> begin;
mysql> select * from user;
mysql> insert into user values (1, 'jeff');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
​
mysql> select * from user;

T2:


mysql> set global transaction isolation level repeatable read;      
​
mysql> begin;
mysql> insert into user values (1, 'jeff');
mysql> commit;

T1 事务检测表中是否有 id 为 1 的记录,没有则插入

T2 插入干扰记录,造成T1出现幻读。

上例中需要确保T1事务执行begin后才开始执行事务T2。

上例中T1就发生了幻读,因为 T1读取的数据状态与后面的动作发生了语义上的冲突:查询的时候明明提示记录不存在,插入的时候去提示主键重复,类似于出现幻影,因而称之为幻读。

如何消除幻读

MySQL当前有两种方式可以消除幻读:

1. 通过对select操作手动加行X(SELECT ... FOR UPDATE )。原因是InnoDB中行锁锁定的
索引,纵然当前记录不存在,当前事务也会获得一把记录锁(记录存在就加行X锁,不
存在就加next-key lock间隙X锁),这样其他事务则无法插入此索引的记录,杜绝幻
读。
2. 进一步提升隔离级别为SERIALIZABLE
测试一下效果


mysql> begin;
​
mysql> select * from user where id = 2 for update;
mysql> insert into user values (2, 'tony');

mysql> commit;

T2:


mysql> begin;
​
mysql> insert into user values (2, 'jimmy');
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'

现在T1查询时携带了for update,在Innodb内会对该索引加锁(即使当前不存在),于是事务T2的insert会被阻塞直到T1显示提交,这样T1成功了,对于T1来说,幻读确实被消除了,但T2的插入会报主键重复,这也符合预期。

至于另外一种提升隔离级别消除幻读的方式感兴趣的可以自己尝试,这里不再重复,其本质是类似的,只是让系统代替了手工加锁。

总结

RR作为 mysql 事务默认隔离级别,是事务安全与性能的折中,正确认识幻读后,开发者便可以根据需求自行决定是否需要防止幻读。

SERIALIZABLE则是悲观的认为幻读时刻都会发生,故会自动的隐式的对事务所需资源加排它锁,其他事务访问此资源会被阻塞等待,故事务是安全的,但需要认真考虑性能。

InnoDB的锁是针对索引,这点需要引起注意。对行记录加锁,如果存在,加X锁,否则会加 next-key lock / gap 锁 / 间隙锁,故InnoDB可以实现事务对某记录的预先占用,只要本事务还在,其他事务就别想占有它。关于锁,后面还会再有专门的文章讨论。

以上就是详解MySQL 幻读及如何消除的详细内容,更多关于MySQL 幻读及消除的资料请关注编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: 详解MySQL幻读及如何消除

本文链接: https://lsjlt.com/news/122532.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详解MySQL 幻读及如何消除
    这是一篇数据库隔离级别的科普文章,旨在了解数据库中著名的幻读现象,为了专注,对脏读、不可重复读不作讨论。 事务隔离级别 MySQL有四级事务隔离级别: 读未提交 READ-UNCOMMITTED: 存在脏读,不可...
    99+
    2022-05-29
    MySQL 幻读 MySQL 幻读消除
  • 详解MySQL幻读及如何消除
    目录事务隔离级别 什么是幻读 如何消除幻读 总结 这是一篇数据库隔离级别的科普文章,旨在了解数据库中著名的幻读现象,为了专注,对脏读、不可重复读不作讨论。 事务隔离级别 MySQL...
    99+
    2024-04-02
  • MySQL中幻读及消除的示例分析
    小编给大家分享一下MySQL中幻读及消除的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!事务隔离级别MySQL有四级事务隔离级别:读未提交 READ-UN...
    99+
    2023-06-14
  • 如何解决mysql幻读
    mysql中出现幻读的两种解决方法多版本并发控制(MVCC)多数数据库都实现了多版本并发控制,并且都是靠保存数据快照来实现的。事务每次取数据的时候都会取创建版本小于当前事务版本的数据,以及过期版本大于当前版本的数据。其原理时将历史数据存一份...
    99+
    2024-04-02
  • mysql幻读详解实例以及解决办法
    目录事务隔离级别(tx_isolation)幻读RR级别下防止幻读SERIALIZABLE级别杜绝幻读总结脏读/不可重复读的概念都比较容易理解和掌握,这里不在讨论 事务隔离级别(tx_isolation) mysql 有...
    99+
    2022-06-16
    mysql脏读幻读 MySQL幻读 mysql中的幻读
  • 一文详解MySQL是如何解决幻读的
    目录前言什么是幻读?什么是普通读和当前读?普通读当前读普通读是如何避免幻读的?当前读是如何避免幻读的?总结前言 SQL标准中定义了4种隔离级别,分别是读未提交、读已提交、可重复读以及序列化。不同的隔离级别下,可以解决不同...
    99+
    2023-04-19
    mysql幻读 怎样解决mysql的幻读 mysql避免幻读
  • MySQL如何解决幻读问题
    目录前言一、什么是幻读?二、幻读有什么问题?(1)需要单独解决(2)间隙锁引发的并发度三、如何解决幻读?三、总结前言   我们知道MySQL在可重复读隔离级别下别的事物提交的内容,是看不到的。而可提交隔离级别下是可以...
    99+
    2022-05-22
    MySQL 幻读
  • Mysql数据库事务的脏读幻读及不可重复读详解
    目录一、什么是数据库事务二、事务的ACID原则1. 原子性(Atomicity)2. 一致性(Consistency)3. 持久性(Durability)4. 隔离性(Isolati...
    99+
    2024-04-02
  • 如何解决MySQL的幻读问题
    如何解决MySQL的幻读问题?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。  1、MVCC快照,将历史数据存一份快照,在其...
    99+
    2024-04-02
  • Mysql中的innoDB如何解决幻读
    目录1.Mysql的事务隔离级别2. 什么是幻读3. InnoDB如何解决幻读的问题4. 总结1.Mysql的事务隔离级别 这四种隔离级别,当存在多个事务并发冲突的时候,可能会出现...
    99+
    2024-04-02
  • 详解MySQL的脏读、幻读和不可重复读
    MySQL的脏读、幻读和不可重复读是数据库事务处理中的三种常见问题,它们都涉及到数据的一致性和并发性。本文将详细介绍这三种问题,并给出相应的解决方案和示例代码。 一、脏读(Dirty Read) 脏读是指一个事务读取了另一个事务未提交...
    99+
    2023-09-29
    mysql 数据库
  • mysql幻读是什么及怎么解决
    MySQL幻读是指在一个事务中,读取到了其他事务插入的新数据,导致前后两次查询结果不一致的现象。解决幻读的方法有以下几种:1. 采用...
    99+
    2023-10-23
    mysql
  • Mysql事务并发脏读+不可重复读+幻读详解
    目录Mysql的事务隔离级别脏读不可重复读幻读总结Mysql的事务隔离级别 Mysql有四种事务隔离级别,这四种隔离级别代表当存在多个事务并发冲突时,可能出现的脏读、不可重复读、幻...
    99+
    2024-04-02
  • 你知道MySQL是如何解决幻读的吗?
    前言 SQL标准中定义了4种隔离级别,分别是读未提交、读已提交、可重复读以及序列化。不同的隔离级别下,可以解决不同的并发问题,如下图所示。当然MySQL也基本遵循了这个标准,但是在实现上稍有不同。 本文重点探讨下MySQL是如何解决幻读问题...
    99+
    2023-09-12
    mysql 数据库
  • 【MySQL】MVCC是如何解决快照读下的幻读问题的
    文章目录 LBCC当前读 MVCC隐藏列undo logRead View 总结 我们从上文中了解到InnoDB默认的事务隔离级别是repeatable read(后文中用简称RR),它为了解决该隔离级别下的幻读的并发问...
    99+
    2023-08-17
    mysql 数据库 java mvcc 快照读
  • mysql读锁及写锁详解
    本篇内容介绍了“mysql读锁及写锁详解”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • MySQL如何消除重复行
    这篇文章给大家分享的是有关MySQL如何消除重复行的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。sql语句 ----------------全部字段重复-------------...
    99+
    2024-04-02
  • 详解如何消除axios拦截中的if
    目录基本拦截设计轮子思考方向轮子骨架详细实现实践总结基本拦截 axios的响应错误拦截中,难免会对error.status做各种各样的if判断,又或者switch。为了防止枯燥乏味的...
    99+
    2024-04-02
  • 详解MySQL主从复制及读写分离
    目录前言一、相关概述二、读写分离三、MySQL主从复制实验部署四、MySQL读写分离实验前言 在企业实际应用中,成熟的业务通常数据量都比较大,而单台MySQL服务器在安全性、高可用性...
    99+
    2024-04-02
  • SpringBoot详解MySQL如何实现读写分离
    目录前言一、主从数据源的配置二、数据源路由的配置三、数据源上下文环境四、切换注解和Aop配置五、用法以及测试六、总结前言 首先思考一个问题:在高并发的场景中,关于数据库都有哪些优化的...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作