首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

mysql幻读与脏读

基础概念

幻读(Phantom Read)脏读(Dirty Read) 是数据库事务隔离级别中的两种现象。

  • 脏读:当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
  • 幻读:当一个事务正在访问数据并且对数据进行修改,这种修改已经提交了,这时另一个事务也访问了这个数据,但是另外一个事务访问的时候发现数据已经被修改了,就好像产生了幻觉。

相关优势、类型

数据库事务的隔离级别有四种:

  1. 读未提交(Read Uncommitted):最低的隔离级别,允许脏读、不可重复读和幻读。
  2. 读已提交(Read Committed):允许不可重复读和幻读,但不允许脏读。
  3. 可重复读(Repeatable Read):不允许脏读和不可重复读,但可能出现幻读。
  4. 串行化(Serializable):最高的隔离级别,事务串行执行,不会出现脏读、不可重复读和幻读。

应用场景

  • 脏读:通常出现在并发访问的场景中,当一个事务正在修改数据但尚未提交时,另一个事务读取了这个未提交的数据。
  • 幻读:通常出现在范围查询的场景中,当一个事务正在修改数据并提交后,另一个事务在相同的范围内查询数据时,可能会看到新插入的数据。

问题及解决方法

为什么会这样?

  • 脏读:是因为事务的隔离级别设置得太低,允许读取未提交的数据。
  • 幻读:是因为在可重复读的隔离级别下,范围查询可能会看到新插入的数据。

原因是什么?

  • 脏读:主要是由于事务的隔离级别设置不当。
  • 幻读:主要是由于数据库在处理范围查询时的机制导致的。

如何解决这些问题?

  1. 提高事务隔离级别
    • 将隔离级别提高到“读已提交”可以避免脏读。
    • 将隔离级别提高到“串行化”可以避免脏读、不可重复读和幻读,但会降低并发性能。
  • 使用锁
    • 在读取数据时使用共享锁(S锁),在修改数据时使用排他锁(X锁),可以避免脏读和不可重复读。
    • 使用范围锁(Range Lock)可以避免幻读。
  • 使用乐观锁和悲观锁
    • 乐观锁:假设数据冲突不频繁,通过版本号或时间戳来检测冲突,并在提交时进行验证。
    • 悲观锁:假设数据冲突频繁,在读取数据时就加锁,防止其他事务修改数据。

示例代码

以下是一个简单的示例,展示如何在MySQL中使用事务隔离级别来避免脏读和幻读:

代码语言:txt
复制
-- 设置事务隔离级别为读已提交
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

START TRANSACTION;

-- 读取数据
SELECT * FROM users WHERE id = 1;

-- 修改数据
UPDATE users SET name = 'new_name' WHERE id = 1;

-- 提交事务
COMMIT;

参考链接

通过以上方法,可以有效避免脏读和幻读问题,确保数据库事务的完整性和一致性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

mysql、不可重复读

:有个英雄表如下图所示图片第一天 小张 往里面插入数据:BEGIN;INSERT INTO heros_temp values(4, '吕布');小张还没有提交事务的时候,小李对数据表进行了访问,小张看到的结果如下图片小李读到了小张还没有提交的数据...,我们称之为“”不可重复读小张想查看 id=1 的英雄是谁,于是他进行了 SQL 查询:SELECT name FROM heros_temp WHERE id = 1;图片然而此时,小李开始了一个事务操作...小张想要看下数据表里都有哪些英雄图片这时当小张执行完之后,小李又开始了一个事务,往数据库里插入一个新的英雄“吕布”BEGIN;INSERT INTO heros_temp values(4, '吕布...这种异常情况我们称之为“”。总结:读到了其他事务还没有提交的数据。不可重复读:对某数据进行读取,发现两次读取的结果不同,也就是说没有读到相同的内容。...:事务 A 根据条件查询得到了 N 条数据,但此时事务 B 更改或者增加了 M 条符合事务 A 查询条件的数据,这样当事务 A 再次进行查询的时候发现会有 N+M 条数据,产生了

81150

Mysql 、不可重复读、

具体来说,这就有可能产生、不可重复读和。事务是逻辑上的一组操作,要么全部执行,要么全部不执行一个事务读取到了另一个未提交事务修改的数据。...Read Uncommitted(未提交):它是性能最好的,事务中的修改,即使没有提交,其他事务也可以看得到,会导致“”、“”和“不可重复读取”。...READ COMMITTED(已提交):允许读取并发事务已经提交的数据,不允许读取另一个并行事务已修改但未提交的数据,避免了“”,但不能避免“”和“不可重复读取”。...Mysql的默认隔离级别,避免了“读取”和“不可重复读取”的情况,但不能避免“”。Serializable (串行化):一个事务处理的时候,其他事务都等着。...的时候加共享锁,也就是其他事务可以并发,但是不能写。写的时候加排它锁,其他事务不能并发写也不能并发。这样“”、“不可重复读”、“”都能避免了,但此隔离级别性能最低。

15310
  • MySQL事务(、不可重复读、)

    、Read committed 、Repeatable read (默认)、Serializable ,这四个级别中的后三个级别可以逐个解决 、不可重复读 、这几类问题   1....的情况:对于两个事务T1T2,T1读取了已经被T2更新但是还没有提交的字段之后,若此时T2回滚,T1读取的内容就是临时并且无效的   开启两个mysql客户端,并创建一张测试表transaction...不同隔离级别所解决的事务并发问题 不可重复读READ UNCOMMITTED111READ COMMITTED011REPEATABLE READ001SERIALIZABLE000 READ...UNCOMMITTED级别不做演示,其隔离性最低,会出现、不可重复读、等所有情况。...READ COMMITTED级别能够避免,下面来进行演示: 1.避免(一个事务读取到另一个事务未提交的数据) 2.

    1.1K10

    不可重复读

    最近在读 《MySQL 技术内幕 InnoDB 存储引擎》,里面提到的各种概念都很新鲜,以前听说过、不可重复读,但是对于概念不甚了解,于是查了一下,这里做个笔记。...不同的事务隔离级别会导致不同的问题: 、不可重复读的概念 所谓是指一个事务中访问到了另外一个事务未提交的数据,如下图: 如果会话 2 更新 age 为 10,但是在 commit...这就是 一个事务读取2次,得到的记录条数不一致: 上图很明显的表示了这个情况,由于在会话 1 之间插入了一个新的值,所以得到的两次数据就不一样了。...它能够避免读取,而且具有较好的并发性能。尽管它会导致不可重复读、和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。...参考 数据库的、不可重复读 ,不可重复读, 何为、不可重复读、 发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/111668.html原文链接

    56710

    Mysql、不可重复读(二)

    Mysql、不可重复读引言在数据库领域中,和不可重复读是常见的问题,特别是在并发操作的环境下。本文将详细介绍这三个问题的定义、原因以及如何通过Mysql来解决它们。1....(Dirty Read)指的是一个事务读取到了另一个事务未提交的数据。当一个事务修改数据但还没有提交时,另一个事务读取到了这个未提交的数据,并做出了相应的操作。...事务2在事务1未提交的情况下读取到了这条记录,导致的问题。2....(Phantom Read)指的是一个事务在读取某个范围内的记录时,另一个事务在该范围内插入了新的记录,导致第一个事务再次读取到了该范围内的新记录,就像幻觉一样。...当事务1再次读取数据时,发现又多了一条记录,这就是的问题。3.

    19600

    详解-不可重复读

    最近在读 《MySQL 技术内幕 InnoDB 存储引擎》,里面提到的各种概念都很新鲜,以前听说过、不可重复读,但是对于概念不甚了解,于是查了一下,这里做个笔记。...不同的事务隔离级别会导致不同的问题: 、不可重复读的概念 所谓是指一个事务中访问到了另外一个事务未提交的数据,如下图: 如果会话 2 更新 age 为 10,但是在 commit...这就是 一个事务读取2次,得到的记录条数不一致: 上图很明显的表示了这个情况,由于在会话 1 之间插入了一个新的值,所以得到的两次数据就不一样了。...可重复读取(Repeatable Read) 可重复读取(Repeatable Read):禁止不可重复读取和读取,但是有时可能出现读数据。这可以通过“共享锁”和“排他写锁”实现。...它能够避免读取,而且具有较好的并发性能。尽管它会导致不可重复读、和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

    50810

    MySQL、不可重复度是什么

    什么是又称为无效数据读取,指在数据库访问中,事务T1修改了某个数值,随后事务T2读取了该数值,而后因某种原因,T1撤销了对该数值的修改,导致T2读取到的数据变为无效。...什么是是指在事务非独立执行时出现的现象,举例来说,第一个事务对表中的数据进行了修改,涉及到表中的“全部数据行”。与此同时,第二个事务也修改了该表的数据,插入了“一行新数据”。...一般解决的方法是通过增加范围锁(RangeS),将检测锁的范围限定为只读,这样便可以避免的发生。...值得注意的是,是不可重复读的一种特殊情况:在事务没有获取范围锁的情况下执行SELECT … WHERE操作时可能会导致现象的发生。...扩展知识之事务隔离级别、不可重复读和这三种异常现象是在SQL-92标准中定义的,同时,SQL-92标准还确定了4种隔离级别来处理这些异常情况,按照严格程度从高到低排列分别为:顺序执行(Serializable

    11110

    MySQL、不可重复度是什么

    什么是又称为无效数据读取,指在数据库访问中,事务T1修改了某个数值,随后事务T2读取了该数值,而后因某种原因,T1撤销了对该数值的修改,导致T2读取到的数据变为无效。...什么是是指在事务非独立执行时出现的现象,举例来说,第一个事务对表中的数据进行了修改,涉及到表中的“全部数据行”。与此同时,第二个事务也修改了该表的数据,插入了“一行新数据”。...一般解决的方法是通过增加范围锁(RangeS),将检测锁的范围限定为只读,这样便可以避免的发生。...值得注意的是,是不可重复读的一种特殊情况:在事务没有获取范围锁的情况下执行SELECT … WHERE操作时可能会导致现象的发生。...扩展知识之事务隔离级别、不可重复读和这三种异常现象是在SQL-92标准中定义的,同时,SQL-92标准还确定了4种隔离级别来处理这些异常情况,按照严格程度从高到低排列分别为:顺序执行(Serializable

    35610

    ,不可重复读,

    MySQL事务隔离级别: 在介绍,不可重复读,现象之前,我们先来了解MySQL的事务隔离级别,因为,不可重复读,等现象都是由数据库里的事务隔离级别来决定是否可能发生的。...)隔离级别下不存在。...现象: 在默认的事务隔离级别下,我们是无法读取到未提交的数据的,在能够读取到未提交数据的事务隔离级别下,才会出现现象。...用言语来描述可能有点抽象、不好理解,下面我们打开两个MySQL客户端,来进行现象的实验: 1.使用SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED...这就是现象,此现象称之为因为读取出来的是无效数据,无效数据就等于是垃圾数据垃圾就当然就是的所以才叫,而且如果我们以这个数据作为某些参数的话,必然会出现错误。

    1.7K10

    详解-不可重复读

    最近在读 《MySQL 技术内幕 InnoDB 存储引擎》,里面提到的各种概念都很新鲜,以前听说过、不可重复读,但是对于概念不甚了解,于是查了一下,这里做个笔记。...、不可重复读的概念 所谓是指一个事务中访问到了另外一个事务未提交的数据,如下图: ?...这就是 一个事务读取2次,得到的记录条数不一致: ? 上图很明显的表示了这个情况,由于在会话 1 之间插入了一个新的值,所以得到的两次数据就不一样了。...可重复读取(Repeatable Read) 可重复读取(Repeatable Read):禁止不可重复读取和读取,但是有时可能出现读数据。这可以通过“共享锁”和“排他写锁”实现。...它能够避免读取,而且具有较好的并发性能。尽管它会导致不可重复读、和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

    6.5K41

    MySQLMySQL事务的问题:、不可重复读

    MySQL事务的问题:、不可重复读 在上一篇文章中,我们已经学习过了事务相关的基础知识,今天,我们继续学习事务有可能带来的一些问题。...-- my.cnf [server] transaction-isolation = READ-UNCOMMITTED 的意思就是两个事务同时在运行,其中 A 事务修改了某个字段,B 事务读取了这个字段...很明显,这就产生了问题,这个就是带来的结果,一致性出现了问题。 不可重复读 不可重复读是啥意思呢?...; +----------+ | username | +----------+ | aaa | +----------+ 1 row in set (0.00 sec) 最后一个...确实,它们非常类似,但是,更强调的是聚合操作结果,而不是单一一条数据的修改,这就是它们两个之间最本质的区别。

    16710

    MYSQL事件隔离级别以及复读,,的理解

    一.mysql事件隔离级别 1未提交(READUNCOMMITTED) 另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据()( 隔离级别最低,并发性能高 ) 2....但是,会有现象(稍后解释)。...会出(锁定所读取的所有行) 4.串行化(SERIALIZABLE) 操作会隐式获取共享锁,可以保证不同事务间的互斥(锁表) 二.、不可重复读、、复读 1. 当前事务读到的数据是别的事务想要修改成为的但是没有修改成功的数据...2.不可重复读 当前事务先进行了一次数据读取,然后再次读取到的数据是别的事务修改成功的数据,导致两次读取到的数据不匹配,也就照应了不可重复读的语义 3. 当前事务第一次取到的数据比后来读取到数据条目少或者增加...,针对数据的删增 4.复读 当前事务先进行了一次数据读取,然后再次读取到的数据是别的事务修改之前的数据,两次数据相同

    72110

    MySQL InnoDB四个事务级别 、不重复读、

    MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”(REPEATABLE READ)。 1).未提交(READUNCOMMITTED)。...会出现不可重复读、问题(锁定正在读取的行) 3).可重复读(REPEATABLEREAD)。...但是,会有现象(稍后解释)。会出(锁定所读取的所有行)。 4).串行化(SERIALIZABLE)。操作会隐式获取共享锁,可以保证不同事务间的互斥(锁表)。...解决了读后,会遇到,同一个事务执行过程中,另外一个事务提交了新数据,因此本事务先后两次读到的数据结果会不一致。 3).。... 首先区分页和数据 页是内存的缓冲池中已经修改的page,未及时flush到硬盘,但已经写到redo log中。

    1.4K60

    mysql事务隔离级别不可重复读详解

    该级别解决了RC不可重复读的问题,但是存在问题(读后面会详解)。...二、/不可重复读/ 2.1 ? 验证: a. 找一个mysql环境,建一个测试表t_people,就2列 id ,name b....很显然:如果有问题出现,就更加保证不了“可重复读”。 2.2 不可重复读 ? 将事务隔离级别设置成read committed(即:已提交),可解决问题,但满足不了“可重复读需求”。...2.4 串行化 从db层面,要想同时解决、不可重复读、,只有串行化这个级别可以做到。...小结: 隔离级别 存在的问题 未提交 、不可重复读、 已提交 不可重复读、 可重复读 串行化 性能问题 隔离级别越严格,db综合性能越低。

    1.1K20

    MySQL入门】之细说及不可重复读

    、不可重复读 、这几类问题。...隔离级别 不可重复读 未提交(Read uncommitted) 可能 可能 可能 已提交(Read committed) 不可能 可能 可能 可重复读(Repeatable read)...这种情况也叫不可重复读,允许的发生,是oracle数据库的默认隔离级别。 3. Repeatable Read(重复读) mysql的默认级别。...避免了、不可重复读和的发生。 4. Serializable(序列化) 最高隔离级别。所有事务操作依次顺序执行。会导致大量的超时以及锁竞争,同时导致并发度下降,性能最差。不建议生产使用。...四、不同事务级别带来的并发问题 1. 发生在一个事务A读取了被另一个事务B修改,但是还未提交的数据。假如B回退,则事务A读取的是无效的数据。 ?

    84410

    、不可重复读和现象

    而由于一个事务在机器层面可能需要几条指令完成,这也意味着它在并发时会出现如下问题:、不可重复读和,下面以MySQL为例详细介绍在什么情况下可能会出现上述问题。...Read uncommitted(未提交) 此事务隔离级别会出现现象*(事务的修改,即使没有提交,其他事务也能看的到),不建议在生产环境中去使用。...实验-> 现象 查看隔离级别 show variables like 'tx_iso%'; 修改隔离级别 mysql> set tx_isolation='READ-UNCOMMITTED'; 注意...Repeatable Read(可重复读) 这是MySQL默认隔离级别,解决不可重复读,但是还会出现存在现象。...Serializable(串行化) 串行化解决了、不可重复读、现象,但是效率会比较低下。从MVCC并发控制退化为基于锁的并发控制。不区分快照读当前,所有的操作均为当前

    1K20

    什么是、不可重复读、

    、不可重复读、 在现代关系型数据库中,事务机制是非常重要的,假如在多个事务并发操作数据库时,如果没有有效的机制进行避免就会导致出现,不可重复读,。...和不可重复读有些类似,但是强调的是集合的增减,而不是单条数据的更新。 ?...只能防止第一类更新丢失,不能解决,可重复读,,所以很少应用于实际项目。...可以防止和第一类更新丢失,但是不能解决可重复读和的问题。 可重复读 可重复读(Repeatable Read),MySQL默认的隔离级别。...可以防止、不可重复读、第一类更新丢失、第二类更新丢失的问题,不过还是会出现。 串行化 串行化(Serializable),这是最高的隔离级别。

    1.1K20

    什么是和不可重复读?

    在数据库系统中,(Dirty Read)、(Phantom Read)和不可重复读(Non-repeatable Read)是几种常见的并发控制问题。...如何解决和不可重复读问题?下面是一个简单的示例代码,演示了如何通过使用事务和行级锁来解决和不可重复读的问题。...未提交(Read Uncommitted):最低级别的隔离,允许和不可重复读。事务可以读取其他事务未提交的数据,会导致数据的不一致性。...已提交(Read Committed):事务只能读取已经提交的数据,解决了问题。但仍可能出现和不可重复读问题。...这解决了和不可重复读的问题。数据库使用锁机制来阻止其他事务对数据进行修改。可串行化(Serializable):最高级别的隔离,确保事务串行执行,完全消除了和不可重复读的问题。

    2.6K10

    快速理解、不可重复读、和MVCC

    ,平白无故的多了几条数据,成为。...、不可重复读 、 这几类问题。...注:Mysql的默认隔离级别就是Repeatable read。 不可重复读和的区别是:是某一事务读取了另一个事务未提交的数据,而不可重复读则是读取了前一事务提交的数据。...和不可重复读都是读取了另一条已经提交的事务(这点就不同),所不同的是不可重复读查询的都是同一个数据项,而针对的是一批数据整体(比如数据的个数)。 4....Serializable 序列化(串行化) Serializable 是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免、不可重复读,还避免了

    62K2616
    领券