当前位置: 首页 > article >正文

MySql幻读问题

认识具有反复性。

之前以为理解了幻读,最近看黑马的mysql教程以为再次加深了认识。然而现在认为之前的理解都是错误的,而且网上很多关于幻读的解释,都不太准确。

关于幻读的最佳解释还是要看官网mysql官网幻读解释

脏读和不可重复读比较好理解,但有一个容易误解的地方,就是在READ COMMITTED这个隔离级别下,事务A查询某种condition下的结果集为R1,此时事务B插入或者删除了符合这个condition的数据并提交事务。此时事务A再次查询结果集为R2,与R1不一致,个人认为这是幻读,很容易让人以为这是不可重复读。

脏读侧重于读取到了其他事务未提交的数据。而不可重复读侧重于针对单条数据的更新,同一事务中两次查询内容不一致。而幻读侧重于其他事务的插入和删除,导致本事务查询结果集数量和范围不一致。

我们最先认识到的就是MySql隔离级别默认是REPEATABLE READ,这个隔离级别可能出现幻读。由于先入为主,反而容易产生误解,导致很多人在这个隔离级别下演示幻读。然而这个隔离级别下,由于MySql使用了MVCC机制,在事务开启时,会创建一个一致性视图,普通的Select语句即快照读,都是基于这个视图获取数据。这种情况下其他事务无论删除还是插入,都不会影响这个一致性视图。此事务下的普通Select查询结果一致,一定程度上避免了幻读。所以很多教程演示的两次查询结果一致,并没有演示出幻读的现象。当然,很多教程在两次查询中间,会演示事务B插入一条主键为某个值的数据。然后事务A查询这个主键数据不存在,然后做插入操作,结果失败了,然后再次查询结果,这个主键的数据还是不存在。插入失败,会提示主键重复,在insert时会执行当前读,读取的是数据库当前最新的数据,可以查到此主键已经存在,前面查询是不存在的,可以理解为变相的演示出了幻读。

补充

快照读:读取的是事务开启时特定时间点的数据库“快照”数据,基于多版本并发控制(MVCC)机制实现。不管事务执行多久,期间其他事务如何更新提交数据,快照读看到的始终是最初那个时间点的数据版本,保证同一事务内多次读取数据的一致性。例如,在一个长事务中,多次执行普通的SELECT语句,结果都一样。
当前读:读取的是数据库当前最新的、真实的数据状态,无视多版本情况。每次当前读获取的数据反映的都是当下这一瞬间的数据库真实情况,所以不同时间的当前读,获取的数据很可能不同。

执行SELECT… FOR UPDATE 、SELECT… LOCK IN SHARE MODE、UPDATE、DELETE、INSERT语句时,是当前读,因为它们要获取数据库当下最新数据。

在“读已提交”(READ COMMITTED )隔离级别下,MySQL也有MVCC机制,但它无法避免幻读:
在“读已提交”级别,事务每次执行快照读时,都会获取最新已提交事务对应的版本,而非固定在事务开启时的版本。这意味着,新插入并提交的数据能被后续快照读捕捉到,没办法维持同一事务内多次查询结果的稳定性,所以抵御不了幻读。
反观“可重复读”隔离级别,事务开启时生成固定一致性视图,全程基于此视图做快照读,新数据进不来,能较好防控幻读;“读已提交”的MVCC 因频繁更新读取版本,给幻读留了“口子”。


http://www.kler.cn/a/457809.html

相关文章:

  • 工业大数据分析算法实战-day19
  • AE Dressler CESAR 1312 Generator Model User Manual
  • 健身房运动锻炼环境音效、健身房器材、健身房环境、过渡、电影制作后期音效 OcularSounds - CINEMATIC GYM SOUND FX
  • 高性能网络框架--fstack
  • Git如何添加子仓库
  • AE/PR/达芬奇模板:自动光标打字机文字标题移动效果动画模板预设
  • Ubuntu系统部署Mysql8.0后设置不区分大小写
  • openfeign-一些配置
  • 异步爬虫之协程的基本原理
  • 基于Android的校园导航系统
  • 科技驱动|暴雨信息赋能金融行业数智升级
  • RCCL/NCCL中的Transports方式选择:P2P or SHM or NET
  • 部署SenseVoice
  • React 组件的通信方式
  • RAG挑战及其解决方案:实践中的应对策略
  • 嵌入式单片机窗口看门狗控制与实现
  • 【AIGC-ChatGPT副业提示词指令 - 动图】命运织图:一个创新的个人发展分析工具
  • Ajax笔记
  • SCAU高程期末课后习题复习(只放了易错自用)
  • 探索城市空中交通的未来:基于Python的仿真与优化