• mysql 幻读


    什么是幻读?

      InnoDB默认级别为可重复读,可重复读会产生问题就是幻读。事务A按照一定条件进行数据读取,期间事务B插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B新插入的数据称之为幻读。如果事务中都是用快照读,那么不会产生幻读的问题,但是快照读和当前读一起使用的时候就会产生幻读。

      不可重复读侧重于update这种操作,同一条数据前后读起来不一样的情况,幻读侧重于insert delete这种操作,前后两次select 数据的数量会发生变化

      举个例子:

        事务A  第一步  select *       第二步  update 所有字段        第三步  再次select *      

        事务B  执行了insert 一条语句

        幻读第一种情况: 当事务A 刚执行完第一步,事务B insert一条,导致事务A update执行完,再次select发现多了一条数据

        幻读第二种情况: 当事务A 刚执行完第二步,事务B insert一条,导致事务A 再次select 发现有一条数据没有update字段

    InnoDB如何解决幻读的?

      Mvcc+行锁+间隙锁

    什么是间隙锁?

      正常等值条件 并且值存在的情况下加的是行锁

      如果等值条件 值不存在的情况下加的是间隙锁,或者范围查询,加的也是间隙锁

      举个例子:

      

      根据主键id,不只是有五个行锁,还会有六个间隙锁,左开右闭原则,(-∞,5](5,10](10,15](15,20](20,25](25,+supernum]

      例如 select * from table where id = 10 for update;   等值条件,id是存在的,加行锁就可以了

      select * from table where id = 7 for update;  等值条件,id不存在,加(5,10] 间隙锁,这范围间不允许插入数据,直到这个事务提交完成释放锁

      select * from table where id > 24;  范围条件,加间隙锁

      通过行锁+间隙锁的机制保证了事务A select之后,其他事务相应的insert操作会阻塞

    间隙锁跟MVCC一起工作。实现事务处理:

       Repeatable Read隔离级别: 采用Next-key Lock(间隙锁) 来解决幻读问题.因此 Mysql 在Repeatable下面 幻读,可重复读,脏读 三者都不会发生

       Read Committed隔离级别:采用Record锁,不会出现脏读,但是会产生"幻读"问题. 也会出现可重复读

    间隙锁简介:

      MySQL InnoDB支持三种行锁定方式:InnoDB的默认加锁方式是next-key 锁

        行锁(Record Lock):锁直接加在索引记录上面,锁住的是key。

       间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙不变。间隙锁是针对事务隔离级别为可重复读或以上级别而已的。

       Next-Key Lock :行锁和间隙锁组合起来就叫Next-Key Lock。 

      默认情况下,InnoDB工作在可重复读(Repeatable Read)隔离级别下,并且会以Next-Key Lock的方式对数据行进行加锁,这样可以有效防止幻读的发生。Next-Key Lock是行锁和间隙锁的组合,当InnoDB扫描索引记录的时候,会首先对索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。加上间隙锁之后,其他事务就不能在这个间隙修改或者插入记录。 read committed隔离级别下Gap Lock在InnoDB的唯一作用就是防止其他事务的插入操作,以此防止幻读的发生。Innodb自动使用间隙锁的条件:
      (1)必须在Repeatable Read级别下
      (2)检索条件必须有索引(没有索引的话,mysql会全表扫描,那样会锁定整张表所有的记录,包括不存在的记录,此时其他事务不能修改不能删除不能添加)

  • 相关阅读:
    解决vmware Invalid memory setting (sched.mem.min)
    PostgreSQL教程
    rpm包安装过程中依赖问题“libc.so.6 is needed by XXX”解决方法
    使用厂商MIB库查找设备OID值 并实施监控的方法
    【交换机】我司交换机上常用的一些MIB以及对应的OID说明
    CentOS6.8-minimal安装gnome桌面 安装NVC远程桌面连接
    LINUX新建和增加SWAP分区
    Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWo
    类与对象
    Volley框架源代码分析
  • 原文地址:https://www.cnblogs.com/hzzjj/p/15137591.html
Copyright © 2020-2023  润新知