幻读是什么,用什么隔离级别可以防止幻读?

2024-01-23 19:04
文章标签 级别 隔离 防止 幻读

本文主要是介绍幻读是什么,用什么隔离级别可以防止幻读?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        幻读指的是,在同一个事务中,以同样的条件执行的两次查询,第二次查询查到了第一次查询所没查到的数据。

        在mysql的四种隔离级别中,可重复读和串行化两种隔离级别没有幻读问题。那么它们是如何解决幻读问题的呢?

        先说串行化这个隔离级别,串行化是通过加锁的方式,让事务按照顺序串行执行,事务会对整张表加锁,读操作时加共享锁,写操作时加排它锁,总之,事务会对整张表加锁,并且这个锁要到事务结束时才释放,所以串行化这个隔离级别根本就不会有幻读问题。

        再说可重复读,在可重复读这个隔离级别下,快照读是不会有幻读问题的【也可以说快照读用MVCC避免了幻读问题】,只有当前读会有幻读问题,那么什么是快照读和当前读呢?

        快照读读的是快照数据,是由MVCC机制实现的,因为读的是快照数据,所以即便是有其他事务并发修改了数据或者添加了新的数据,也不会对当前事务的快照读造成影响,因为当前事务的快照读读的是同一个版本的快照,所以快照读不会有幻读问题。读已提交 和 可重复读这两种隔离级别下的所有的普通的select查询都是快照读,除了快照读之外就都是当前读了。

        当前读读的永远都是最新版本的数据,当前读会对这些数据加锁,以避免其他的事务并发去修改这些数据,当前读包括:

        1、加共享锁的select:select * from user lock in share mode;

        2、加排它锁的select: select * from user for update;

        3、增删改操作:insert、delete、update。虽然看起来增删改操作与读无关,但其实在增删改之前都要先执行当前读,以将符合条件的数据锁起来,避免其他事务并发去修改它们。

        当前读为什么会有幻读问题呢?

        虽然当前读能够将符合条件的数据加锁,以阻塞其他事务对于这些数据的修改,却不能够避免其他事务添加新的数据,而其他事务添加的新的数据,有可能对于当前事务的当前读造成影响:一旦其他事务所添加的数据是满足我们当前读的条件的,那么当我们在当前事务中再以同样的条件执行一次当前读时,就会读到其他事务添加的那条新的数据,幻读就发生了。分析一下原因,幻读问题的发生是因为,当前读所加的行锁只是锁住了数据库中已存在的满足条件的记录,却不能够避免其他事物添加新数据的操作。为了解决这个问题,InnoDb存储引擎引入了间隙锁。

        间隙锁

        同行锁锁住满足条件的行不同,间隙锁锁住的是行之间的间隙,当为某些间隙添加了间隙锁,其他事务就不能往这些间隙中添加新的数据了,比如:当前读的条件是 5<id<10,那么行锁锁住的是id落在5到10之间的行,而间隙锁锁住的是5到10之间的间隙,如果有其他事务想要添加新的数据,而新数据的id在5到10之间,那么这个添加请求将被阻塞。

        可重复读在当前读模式下,用行锁+间隙锁来解决了幻读问题行锁+间隙锁又叫Next-Key Lock。

这篇关于幻读是什么,用什么隔离级别可以防止幻读?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/637224

相关文章

PHP生成csv格式Excel,秒级别实现excel导出功能

防止报超内存,兼容中文,兼容科学技术法。 爽。。。。很爽。。。。 /*** 告诉浏览器下载csv文件* @param string $filename*/public static function downloadCsv($data, $filename, $encoding = 'utf-8'){header("Content-type: text/csv");header("Conten

MySQL——数据库级别的外键

仅作了解 方式一:在创建表的时候,增加约束(较复杂) CREATE TABLE IF NOT EXISTS grade(`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',`gradename` VARCHAR(50) NOT NULL COMMENT '年级名字',PRIMARY KEY(`gradeid`) )ENGI

java同步锁以及级别升级的理解

首先简单说下先偏向锁、轻量级锁、重量级锁三者各自的应用场景: 偏向锁:只有一个线程进入临界区;轻量级锁:多个线程交替进入临界区;重量级锁:多个线程同时进入临界区。 还要明确的是,偏向锁、轻量级锁都是JVM引入的锁优化手段,目的是降低线程同步的开销。比如以下的同步代码块:   synchronized (lockObject) { // do something } 上述同步代码块

【笔记】事务隔离级别以及MVCC解决幻读

事务提交可能碰到的问题: (1)脏读:事务1对数据进行修改但还没提交,事务2读取修改后的数据,之后事务1执行错误,回滚了,此时事务2的数据是错误的脏数据。 (2)不可重复读:事务1读取数据1后,事务2对数据1进行修改,之后事务1的再次读取数据1时,发现前后读取结果不一致 (3)幻读:事务1根据条件查询到一批数据后,事务2删除或增加或修改了某些数据,之后事务1再次根据条件查询,发现读取的数据数量不对

防止在 Qt 中触发信号

在 Qt 中工作时,有时我们需要暂时阻止某些信号的触发。以下是一个经典场景:我们有一个 QCheckBox 对象,当用户勾选或取消勾选时,需要调用一个函数,因此我们将这个函数连接到 stateChanged(int state) 信号。然而,在某些条件下,我们在代码中更改 QCheckBox 的状态,这会导致触发不需要的信号。那么如何在特定情况下防止信号触发呢? 使用 clicked 信号 如

金蝶盘点机金蝶PDA外购入库单校验防止收错货实现商品品种和数量校验

采购入库单校验 单据校验,是在电脑上已经存在这个单据,然后对商品实物跟单据进行核对,校验品种和数量。 传统的【采购入库单】校验方式是,供应商送货来,仓管员拿着纸质的【采购入库单】清点商品数量, 并一行行的记录商品数量,这个过程如果商品品种几十种,几百种,就很容核对错误,而且费时费力,搞得头晕眼花,工作强度比较大,对仓管员的责任心和细心程度要求比较高。 如果使用盘点机PDA进行【采购入库

轻松上手MYSQL:MYSQL事务隔离级别的奇幻之旅

​🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》《MYSQL》 💪🏻 制定明确可量化的目标,坚持默默的做事。 ✨欢迎加入探索MYSQL索引数据结构之旅✨     👋 大家好!文本学习研究事务隔离级别。👋 无论您是刚接触MySQL的初学者,还是希望深入优化性能的资深开发者,这篇文章都将为您揭开MySQL事务隔离级别的神秘面纱,让您掌握其中的奥秘,进而

「JCVI教程」如何绘制CNS级别的共线性图(中)

在「JCVI教程」编码序列或蛋白序列运行共线性分析流程(上)还是有一个尴尬的事情,就是只用到两个物种,不能展示出JCVI画图的方便之处,因此这里参考https://github.com/tanghaibao/jcvi/wiki/MCscan-(Python-version)的分析,只不过画图部分拓展下思路。 首先要运行如下代码获取目的数据 python -m jcvi.apps.fetch p

「JCVI教程」如何绘制CNS级别的共线性图(上)

本教程借鉴https://github.com/tanghaibao/jcvi/wiki/MCscan-(Python-version). 我们先从http://plants.ensembl.org/index.html选择两个物种做分析, 这里选择的就是前两个物种,也就是拟南芥和水稻(得亏没有小麦和玉米) 选择物种 我们下载它的GFF文件,cdna序列和蛋白序列 #A

如何防止高并发

服务器集群就是指将很多服务器集中起来一起进行同一种服务,在客户端看来就象是只有一个服务器 集群可以利用多个计算机进行并行计算从而获得很高的计算速度,也可以用多个计算机做备份,从而使得任何一个机器坏了整个系统还是能正常运行。一旦在服务器上安装并运行了群集服务,该服务器即可加入群集。群集化操作可以减少单点故障数量,并且实现了群集化资源的高可用性。 1   我是这样做的: 1.用sy