http://www.cnblogs.com/itcomputer/articles/5133254.html

不    不可重复读和幻读的区别

当然,   从总的结果来看,   似乎两者都表现为两次读取的结果不一致.

但如果你从控制的角度来看,   两者的区别就比较大
对于前者,   只需要锁住满足条件的记录
对于后者,   要锁住满足条件及其相近的记录

-----------------------------------------------------------

我这么理解是否可以?
避免不可重复读需要锁行就行
避免幻影读则需要锁表

------------------------

####不可重复读和幻读的区别####
很多人容易搞混不可重复读和幻读,确实这两者有些相似。但不可重复读重点在于update和delete,而幻读的重点在于insert。

如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复 读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会 发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。

所以说不可重复读和幻读最大的区别,就在于如何通过锁机制来解决他们产生的问题。

上文说的,是使用悲观锁机制来处理这两种问题,但是MySQL、ORACLE、PostgreSQL等成熟的数据库,出于性能考虑,都是使用了以乐观锁为理论基础的MVCC(多版本并发控制)来避免这两种问题。

####悲观锁和乐观锁####

  • 悲观锁

正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处 于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机 制,也无法保证外部系统不会修改数据)。

在悲观锁的情况下,为了保证事务的隔离性,就需要一致性锁定读。读取数据时给加锁,其它事务无法修改这些数据。修改删除数据时也要加锁,其它事务无法读取这些数据。

  • 乐观锁

相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。

而乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如 果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

要说明的是,MVCC的实现没有固定的规范,每个数据库都会有不同的实现方式,这里讨论的是InnoDB的MVCC。

http://www.cnblogs.com/hellopretty/p/5020093.html

关于幻读

不可重复读
在同一事务中,两次读取同一数据,得到内容不同,侧重点在于数据修改
幻读
同一事务中,用同样的操作读取两次,得到的记录数不相同,幻读的侧重点在于两次读取的纪录数量不一致
不可重复读和幻读在概念上有些交叉,对于不可重复读来说,在同一个事务中,如果读取到的记录数量发生变化,也可以看作是一种不可重复读,同样,对于幻读来说,同一个事务中的读取结果数量一致,但是内容发生了变化,也可以看成是一种不可重复读。
对于mysql,这里讨论一下read committed和repeatable read两个事务隔离级别的不可重复读和幻读:
read committed:
在read committed隔离级别下,存在不可重复读和幻读现象。
起两个事务1和2,1采用快照读读取数据,2修改其中一条满足1查询条件的数据并提交,这时1再快照读一次,就会发现2添加的记录,这就是不可重复读。但如果1采用当前读方式读取数据,由于读取数据的时候会给满足条件的数据加锁,因此,事务2无法修改数据内容,如果单纯从数据内容发生变化这个方面来考虑的话,是不会出现不可重复读的问题的。同时,如果考虑到记录数量增减,由于read committed隔离级别并没有gap锁,所以虽然不能修改采用当前读方式锁定的数据,但是可以在查询条件满足的范围内增加新的数据,这也可以看作是一种不可重复读,但显然这种情况划分到幻读更好。
repeatable read:
在repeatable read隔离级别下,mysql不仅解决了不可重复读,还通过gap锁的引入,解决了幻读的问题。
具体分析与上边类似,只是在repeatable隔离级别下,如果事务2对某些数据作了更新,事务1通过快照读已经不会读取到数据变化,所以repeatable read隔离级别解决了不可重复读的问题。同时由于引入了gap锁,事务2也无法在事务1采用当前读的前提下在事务1的查询条件满足范围内插入新的数据,所以记录数量不会发生变化,也就不存在幻读问题。
当隔离级别是可重复读,且禁用innodb_locks_unsafe_for_binlog的情况下,才可以利用gap锁避免幻读,gap锁是为了保证语句级别binlog的串行化。
总结:

  1. 如果仅仅考虑数据内容发生变化来衡量不可重复读,那么只有在read committed隔离级别的快照读中才会出现不可重复读,如果考虑数据数量变化,那么在read committed隔离级别的快照读和当前读中都存在不可重复读现象;
  2. read committed隔离级别下,快照读和当前读都会产生幻读现象;
  3. repeatable read隔离级别下,只有快照读会产生幻读现象,当前读已经通过gap锁的引入消除了幻读现象。
    (何登成大神在博客中将幻读的定义限制在当前读的前提下,个人认为还是幻读和可重复读的具体定义不清晰)

mysql 关于 不可重复读与幻读的解决方案相关推荐

  1. mysql串行化防幻读原理_透彻解读mysql的可重复读、幻读及实现原理

    目录 一.事务的隔离级别 二.mysql怎么实现的可重复读 举例说明MVCC的实现 MVCC逻辑流程-插入 MVCC逻辑流程-删除 MVCC逻辑流程-修改 MVCC逻辑流程-查询 三.幻读 快照读和当 ...

  2. mysql实现可重复读(解决幻读)的原理(MVCC机制的版本链和读视图)

    ​​​​​​​ 版本链 对于使用InnoDB存储引擎的表来说,它的聚簇索引记录中都包含两个必要的隐藏列(row_id并不是必要的,我们创建的表中有主键或者非NULL唯一键时都不会包含row_id列): ...

  3. mysql可重复读和幻读的理解

    mysql可重复读和幻读的理解 可重复读和幻读的定义 最后总结 参考资料 很多教程和书籍对mysql的可重复读和幻读的解释都比较含糊,本文结合原理和其他的考证,深入分析下. 这里讨论的引擎是常用的In ...

  4. mysql 乐观锁 脏读_mysql 丢失更新1和2、脏读、不可重复读和幻读 事务隔离级别 悲观锁 乐观锁...

    事务是现代关系型数据库的核心之一.在多个事务并发操作数据库(多线程.网络并发等)的时候,如果没有有效的避免机制,就会出现以下几种问题: ( 第一类丢失更新 A事务撤销时,把已经提交的B事务的更新数据覆 ...

  5. mysql 幻读和不可重复读_幻读和不可重复读的区别

    MySQl MySql默认的隔离级别为Repeatable Read,因此只会出现幻读的情况. 幻读 事务在插入已经检查过不存在的记录时,惊奇的发现这些数据已经存在了,之前的检测获取到的数据如同鬼影一 ...

  6. MySQL事务(脏读、不可重复读、幻读)

    1. 什么是事务? 是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作:这些操作作为一个整体一起向系统提交,要么都执行.要么都不执行:事务是一组不可再分割的操作集合(工作逻辑单元): ...

  7. MySQL的事务总结(事务特性,隔离级别,脏读,不可重复读,幻读,常见问题)

    MySQL的事务总结(事务四大特性,隔离级别,脏读,幻读) MYSQL官网:https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-iso ...

  8. Mysql有四种事务隔离级别,详解脏读、不可重复读、幻读

    Mysql的事务隔离级别 Mysql有四种事务隔离级别,这四种隔离级别代表当存在多个事务并发冲突时,可能出现的脏读.不可重复读.幻读的问题. 脏读 大家看一下,我们有两个事务,一个是 Transact ...

  9. mysql事务隔离级别之锁实现原理,脏读、不可重复读、幻读出现原因及解决方案

    mysql事务隔离级别原理 观看了很多网上的博客,挺令人伤心,很难找到想要的答案... 一:所需知识 1,mysql中的锁 1.1,读锁(共享锁) 规则:若事务1对数据对象A加上读锁,则事务1只能读A ...

  10. 多图理解MySQL事务的隔离等级,脏读,不可重复读,幻读的几大概念

    2021.3.17 今天在阅读<高性能MySQL>的第一章时,遇到了四大隔离等级的概念,反复琢磨了许久,最后弄出了几张图来帮助记忆,希望对路过的博友们有帮助. 目录 概念定义 三大问题之一 ...

最新文章

  1. php parseurl的反函数,字符串修改(处理)函数
  2. Python基础教程:列表解析
  3. 【Python入门】Python 63个内置函数超级详解
  4. python封装成exe后运行失败_Python的带pandas包的程序封装成exe 2018-01-11
  5. 渗透学习笔记--基础篇--sql注入(数字型)
  6. REFPROP导出温熵数据绘图
  7. [转载]图论500题
  8. dell电脑如何安装ubuntu系统_戴尔T630安装Ubuntu操作系统及Gaussian 09
  9. 【时光纪念】愿有岁月可回头
  10. UDAL - DBProxy internal error问题解决
  11. 信号与槽的Connect详解
  12. 方舟生存进化服务器物品叠加,方舟生存进化:“秤砣虽小压千斤”,叠加和解飞一个都不能少!...
  13. java swing(GUI图形化界面)基础教程2-添加组件
  14. IDEA 中如何将项目打成war包
  15. layui数据表格点击图片放大
  16. 环境类sci期刊排名一区_SCI计算机学术期刊排名(收藏对你有用)
  17. 武器装备自动测试(ATE)系统设计要点
  18. NTP物理机时间同步应用
  19. 如果你在2018面试前端,那这篇文章最好看一看! 原
  20. 天津滨海新区“标签”:AI 与智慧城市深度融合

热门文章

  1. AKM e-compass获取G-sensor的方法
  2. Thymeleaf指定背景图片以及图片如何调整大小
  3. Mac 复制 粘贴问题
  4. word如何绘制斜线表头
  5. 浅聊基于MUI框架的混合开发
  6. onvif python3 推送音频_Python3-onvif协议之相机截图
  7. 计算机用户名uz,Dnuznq全国计算机二级考试vb试题.doc
  8. Unity常用图片格式说明
  9. 单核CPU使用多线程能否提高效率?
  10. java thread queue_java线程池技术(一):ThreadFactory与BlockingQueue