mysql之事务隔离级别以及MVCC

  1.事务特性:ACID

    原子性:undolog--要么全部成功,要么全部失败

     一致性:最核心和最本质的要求

    隔离性:MVCC(多版本并发控制)

    持久性:redo log

   

 

  2.事务的隔离级别

    事务的隔离级别有四种:读未提交、读已提交、可重复读、序列化

    脏读:事务B读取到了事务A已修改但尚未提交的数据,还在这个数据基础上做了操作,此时,如果A事务回滚,B读取的数据无效,不符合一致性要求。

    不可重复读:一个事务范围内两个相同的查询却返回了不同的数据 -----针对修改

    幻读:事务A读取到了事务B的新增数据,不符合隔离性-------针对新增和删除

   3.隔离性引出MVCC

    MVCC:多版本并发控制、是为了在读取数据时不加锁来提高读取效率和并发性的一种手段。 

    数据库并发场景:

      1.读读:不存在任何问题

      2.读写:有线程安全问题、可能出现脏读、幻读、不可重复读

      3.写写:有线程安全问题,可能存在更新丢失等。

     MVCC解决的就是读写时的线程安全问题,线程不用去争抢读写锁。       Mysql两种读方式:

      当前读:读取的是数据的最新版本,而且要保证其他并发事务不能修改当前记录,场景:lock in share mode,for update,updatedelete,insert

      快照都:不加锁的非阻塞读,读取的是历史版本的数据,不是最新的记录,场景:不加锁的select 

    MVCC:multi-Version concurrency control:多版本并发控制,用来解决并发读写的问题,不需要通过加锁来解决 。

  

  MVCC不同事务隔离级别的不同表现:

    RC隔离级别下:当其他事务修改数据之后,可以看到修改之后的值

    RR隔离级别下:当其他事务修改数据之后,看不到修改之后的值 

  MVCC实现原理:

    MVCC模块在Mysql中的具体实现是由三个隐式字段、undo日志、read view三个组件来完成

    三个隐藏字段:

      DB_TRX_ID:6字节,最近修改事务id,记录创建这条记录或者最后一次修改该记录的事务id

      DB_TOLL_PTR:7字节,回滚指针,指向这条记录的上一个版本,用于配合undolog,指向上一个旧版本

      DB_ROW_ID:6字节,隐藏的主键,如果数据表没有主键,那么innodb会自动创建一个row_Id                   undo log: 

 

    undolog被称之为回滚日志,表示在进行insert,delete,update操作的时候产生的方便回滚的日志。

    当进行insert操作的时候,产生的undolog只在事务回滚的时候需要,并且在事务提交之后可以被立刻丢弃。

    当进行update和delete操作的时候,产生的undolog不仅仅在事务回滚的时候需要,在快照读的时候也需要,所以不能随便删除,只有在快照读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除(当数据发生更新和删除操作的时候都只是设置一下老记录的deleted_bit,并不是真正的将过时的记录删除,因为为了节省磁盘空间,innodb有专门的purge线程来清除deleted_bit为true的记录,如果某个记录的deleted_id为true,并且DB_TRX_ID相对于purge线程的read view可见,那么这条记录一定时可以被清除的)。

      readview:最大作用用来做可见性判断 

  案例展示1: 

  案例展示2: 

    说明第二次select并没有生成新的readview,而是沿用了第一次快照时刻的readview。 

  RR隔离级别能否解决幻读问题?

  不能,产生幻读的本质原因

  如果事务中都是用快照读,那么是不会产生幻读问题的,但是当快照读和当前读一起使用的时候就产生了幻读问题 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章