1、事务隔离级别:

在一次事务里面,多次查询之后,结果集的个数不一致的情况叫做幻读。而多或者少的那一行被叫做幻行,也就是说当一个事务在进行读取数据的时候,其他事务对该数据进行了改变。在高并发数据库系统中,需要保证事务与事务之间的隔离性,还有事务本身的一致性。

脏读:比如A事务读取到了B事务还没有提交的数据,因为什么原因B事务回滚了,那么A事务读取的数据和数据库中的数据不同,也就是读到了其他事务没有提交的数据。

读取已提交会产生不可重复读:比如A事务读取数据,开始是100,事务还没有提交,此时B事务对这个数据修改为80,然后提交了事务,此时A事务再次读取就是80,因为B已经提交了,但是两次的结果不一样,就产生了不可重复读的现象。

可重复读:在可重复读中,该sql第一次读取到数据后,就将这些数据加锁(悲观锁),其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据。 

Mysql中读的操作是通过MVCC实现的,如果A事务读取数据,B事务修改了数据提交了,因为MVCC是根据事务粒度生成的ReadView所以不会读取到B事务修改的数据。

        比如:A事务读取数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。

但是MySQL、ORACLE、PostgreSQL等成熟的数据库,出于性能考虑,都是使用了以乐观锁为理论基础的MVCC(多版本并发控制)来实现。

        Mysql的默认隔离级别是可重读,可产生幻读的:幻读仅专指  新插入的行,且在当前读的情况下。

比如:A事务中读取有一条数据是100,B事务中修改为了80,且插入了一条数据,变成了两条事务提交。此时A事务读取的依旧是100,一条数据,但是A事务往里边插入第二条数据的时候,id和B事务插入的数据一样,id是一样的,此时A事务插入不进去,主键冲突,但是查询的时候依旧差不到,这就是幻读的一个例子。

比如:A事务中读取大于5的数据有3条,B事务插入了一条,提交,A事务再次查询大于5的数据发现是4条,就产生了幻读。

2、MVCC以及RC、RR:

MVCC Multi-Version Concurrency Control 就是一个多版本并发控制,即多个不同版本的数据实现并发控制的技术,其基本思想是为每次事务生成一个新版本的数据,在读数据时选择不同版本的数据即可以实现对事务结果的完整性读取,从而不用竞争锁,提高性能这种读是属于快照读,不是当前读,当前读需要加锁,悲观锁。

重要:MVCC 使每个连接到数据库的读者,在某个瞬间看到的是数据库的一个ReadView,不同的隔离级别生成快照的粒度不同,读取已提交生成ReadView的粒度是以每个select单位,所以A事务前后生成的ReadView不同。可重复读生成ReadView的粒度是以事务为粒度生成的,同一个事务只会生成一个ReadView所以避免了可重复读的问题。

当一个 MVCC 数据库需要更新一个一条数据记录的时候,它不会直接用新数据覆盖旧数据,而是将旧数据标记为过时(obsolete)并在别处增加新版本的数据。这样就会有存储多个版本的数据,但是只有一个是最新的。这种方式允许读者读取在他读之前已经存在的数据,即使这些在读的过程中半路被别人修改、删除了,也对先前正在读的用户没有影响。这种多版本的方式避免了填充删除操作在内存和磁盘存储结构造成的空洞的开销,但是需要系统周期性整理(sweep through)以真实删除老的、过时的数据

3、Mysql在的当前读和快照读:

      快照读:读取的是记录数据的可见版本(可能是过期的数据),不用加锁,select时为快照读。MVCC实现。不需要竞争锁。

        当前读:读取的是记录数据的最新版本,并且当前读返回的记录都会加上锁,保证其他事务不会再并发的修改这条记录。update、insert、delete 都是当前读。排它锁

4、Mysql的默认隔离级别是可重读,但是可重复会产生幻读,Mysql是如何实现避免幻读的呢?幻读只存与插入,且是当前读

在Mysql的Innodb引擎中默认开起了间隙锁,幻读是通过间隙锁+行锁方式解决的。

5、Mysql的锁类型:

锁存在的意义就是为了保证事务的隔离性,防止并发产生问题,从而保证一致性。

        基于属性分类:

共享锁 S:共享锁又称之为读锁,简称S锁,当一个事务为数据加上读锁之后,其他事务只能对该数据加读锁,而不能对数据加写锁,所以读锁和写锁是互斥的。直到所有的读锁全部释放之后其他事务才能对其进行加持写锁。共享锁的特性主要是为了支持并发的读取数据,读取数据的时候不支持修改,避免出现不可重读的问题

排它锁 X:排它锁又称之为写锁,简称X锁。当一个事务为数据加上写锁时,其他请求将不能再为数据加任何锁,直到该锁释放之后,其他事务才能对数据进行加锁,排它锁的目的是在数据修改的时候,不允许其他事务同时修改,也不允许其他事务读取,避免了脏读数据问题

        基于锁的状态分类:

意向共享锁:

意向排它锁:

        基于粒度分类:重点

表级锁:表锁指的是对整个表进行加锁,当下一个事务访问该表的数据时,必须等前一个事务释放了锁才能进行对表进行访问。粒度大,并发小。

行级锁:行锁指上锁的时候锁住的是某一行或多行,其他事务访问同一张表时,只有被锁住的记录不能访问,其他记录可以访问。粒度小,并发高。

记录锁:加锁后只对表中的一行记录加上了锁,也就是精准查找,条件字段是唯一索引。

间隙锁:间隙锁是在事务加锁后其锁住的是表记录的某一个区间,当表的相邻id之间出现空隙则会形成一个区间遵循左开右闭原则。间隙锁之间不会冲突。间隙锁是在可重复读隔离级别下才会生效的。

临建锁:

6、ACID的原理:【吊打面试官】大厂面试必问的MySQL事务ACID原理,终于有人讲清楚了!_哔哩哔哩_bilibili

mysql将数据存储到数据库之前都是先通过日志的方式来存储数据,因为日志的存储是顺序存储,可以通过偏移量来控制或者查找,而数据库的持久化存储,是见缝插针,这样可能最大化利用磁盘空间,存储完还需要记录数据的地址,所以相比日志存储比较慢。

原子性的实现:通过Redo logUndo log,重做和回滚。如果事务提交了,那么就会执行Redo log写到数据库,如果没有提交就会执行undo log。

持久性:redo log实现:

7、Mysql的日志

日志系统主要有redo log(重做日志)和binlog(归档日志)。redo log是InnoDB存储引擎层的日志,binlog是MySQL Server层记录的日志, 两者都是记录了某些操作的日志(不是所有)自然有些重复(但两者记录的格式不同)。

         redo log和binlog区别

  • redo log是属于innoDB层面,binlog属于MySQL Server层面的,这样在数据库用别的存储引擎时可以达到一致性的要求。
  • redo log是物理日志,记录该数据页更新的内容;binlog是逻辑日志,记录的是这个更新语句的原始逻辑
  • redo log是循环写,日志空间大小固定;binlog是追加写,是指一份写到一定大小的时候会更换下一个文件,不会覆盖。
  • binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。

Mysql如何解决幻读:相关推荐

  1. mysql java 解决幻读_MySQL 是如何解决幻读的

    MySQL 是如何解决幻读的 一.什么是幻读 在一次事务里面,多次查询之后,结果集的个数不一致的情况叫做幻读. 而多出来或者少的哪一行被叫做 幻行 二.为什么要解决幻读 在高并发数据库系统中,需要保证 ...

  2. mysql rr解决幻读吗_mysql rr隔离级别解决幻读了吗

    以下内容全部基于innodb. 虽然下面有很多概念很浅显,但还是要解释一下 什么是幻读? 当一个事务在多次查询中,发现了一行不是在当前事务中添加的数据.出现这种问题就叫做幻读. 关于四种隔离级别 未提 ...

  3. MySQL中的InnoDB是怎么解决幻读的?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | Aaron_涛 来源 | blog.csdn. ...

  4. mysql 快照读 幻读,InnoDB的MVCC如何解决不可重复读和快照读的幻读,当前读用next-key解决幻读...

    InnoDB默认的隔离级别是RR(可重复读),可以解决脏读和不可重复读,只解决了快照读情况下的幻读问题,当前读情况下解决幻读问题得靠next-key锁. mysql如何实现避免幻读: 在快照读读情况下 ...

  5. MySQL 到底是怎么解决幻读的?

    作者:LastSun https://www.cnblogs.com/wdy1184/p/10655180.html 一.什么是幻读 在一次事务里面,多次查询之后,结果集的个数不一致的情况叫做幻读.而 ...

  6. mysql幻读和不可重复读的区别_面试官:MySQL的可重复读级别能解决幻读吗

    Java面试笔试面经.Java技术每天学习一点 Java面试 关注不迷路 作者:宁愿. 来源:https://juejin.im/post/5c9040e95188252d92095a9e 引言 之前 ...

  7. mysql mvcc和行锁_mysql在RR的隔离级别下,究竟是通过MVCC解决幻读的还是通过行锁的next key算法解决的?...

    首先,我们需要搞懂几个隔离级别的意思和每个隔离级别会出现的问题.隔离级别分为:读未提交,读提交,可重复读和可串行化. 读未提交是最低级别的隔离级别,表示当一个事务还没有提交时,他所做的变更就被别的事务 ...

  8. 不可重复读和幻读的区别_面试官:MySQL的可重复读级别能解决幻读吗

    Java面试笔试面经.Java技术每天学习一点 Java面试 关注不迷路 作者:宁愿. 来源:https://juejin.im/post/5c9040e95188252d92095a9e 引言 之前 ...

  9. mysql行锁怎么读_MySQL锁(三)行锁:幻读是什么?如何解决幻读?

    概述 前面两篇文章介绍了MySQL的全局锁和表级锁,今天就介绍一下MySQL的行锁. MySQL的行锁是各个引擎内部实现的,不是所有的引擎支持行锁,例如MyISAM就不支持行锁. 不支持行锁就意味着在 ...

  10. Mysql RR级别下如何解决幻读

    快照读 在RR级别下,Mysql是根据MVCC来解决快照读时发生的幻读现象,简单来说就是利用了版本链以及Read View来实现的,RR下只有事务刚一开始时才会产生Read View,后续都会使用这个 ...

最新文章

  1. Linux 守护进程,编写(转载)
  2. 【裴蜀定理】[HAOI2011]向量
  3. 多线程-010-后台线程
  4. 旅游(树形dp求树的最大独立集)
  5. spark sql 优化心得
  6. Android 优化布局层次结构
  7. Tensorflow:tensor数据类型转换、计算和变换
  8. vue的下拉框如何回显_JAVA学习笔记系列:菜鸟Vue学习笔记(三)
  9. Dex2Oat执行参数总结
  10. 中e管家投资理财收益最大化技巧
  11. 软件设计师---程序设计语言
  12. Unity3D接入Android第三方SDK流程
  13. 鹏哥C语言红皮书(14-19)
  14. mysql中information_schema数据库
  15. 韩商言喊你来使用模切ERP系统
  16. 新中新DKQ-A16D身份证读卡器C#对接程序出坑记
  17. 错误:Unfortunately you can‘t have non-Gradle Java modules and Android-Gradle modules in one project.
  18. QPainter和QPainterPath理解
  19. 关于上传文件时,服务器选择列表为空的解决办法
  20. java代码中如何嵌入c语言,Android中Java代码与C的互相调用(JNI的简单使用)

热门文章

  1. java分词取词_中文自动分词技术
  2. HP惠普笔记本Microsoft ACPI Compliant System未知设备的解决办法
  3. BlendMask 论文学习
  4. 用python读取YUV文件 转RGB 8bit/10bit通用
  5. transition使用
  6. LVM实现将2块磁盘总空间“合二为一”并挂载到同一目录/移除磁盘
  7. 士不可以不弘毅,任重而道远
  8. 玩转Python,30行Python代码刷王者荣耀金币
  9. Python拓展dict类
  10. kiv8测量方法_特殊的长度测量方法-初二物理长度的测量