zoukankan      html  css  js  c++  java
  • MySQL脏读、不可重复读、幻读及MVCC

    脏读:

    image-20210831100238416

    脏读是指事务读取到其他事务没提交的数据。

    不可重复读:

    image-20210831100532688

    不可重复读是指在同一次事务中前后查询不一致的问题。

    幻读:

    image-20210831101022899

    幻读是一次事务中前后数据量发生变化,导致用户遇到不可预料的问题。

    小结:

    脏读指读取到其他事务正在处理的未提交的数据。
    不可重复读指并发更新时,另一个事务前后查询相同数据时的数据不一致。
    幻读指并发新增、删除这种会产生数量变化的操作时,另一个事务前后查询相同数据不一致的问题。

    事务隔离级别

    image-20210831101923121

    获取当前事务隔离界别,默认RR可重复读
    SHOW VARIABLES LIKE 'transaction_isolation'; # REPEATABLE-READ

    设置当前会话事务隔离级别为“读未提交”
    SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

    MySQL 5.1以后默认存储引擎就是InnoDB,因此MySQL默认RR也能解决幻读问题。

    MVCC

    ​ 在MySQL InnoDB存储引擎下RC、RR基于MVCC(多版本并发控制)进行并发事务控制。MVCC是基于”数据版本”对并发事务进行访问。

    image-20210831103239033

    RR级别:Select1=张三 Select2=张三
    RC级别:Select1=张三 Select2=张小三
    RC级别下出现了“不可重复读”

    image-20210831103730993

    UNDO_LOG不是会被删除吗?中间数据万一被删了版本链不就断了?
    UNDO_LOG版本链不是立即删除,MySQL会确保版本链数据不再被“引用”后再进行删除。

    ReadView是什么?
    ReadView是“快照读”SQL执行时MVCC提取数据的依据。
    快照读就是最普通的Select查询语句。
    当前读指代执行下列语句时进行数据读取的方式。
    Insert、Update、Delete、
    Select...for update
    Select...lock in share mode

    ReadView是一个数据结构,包含4个字段

    • m_ids:当前活跃的事务编号集合
    • min_trx_id:最小活跃事务编号
    • max_trx_id:预分配事务编号,当前最大事务编号+1
    • creator_trx_id:ReadView创建者的事务编号

    读已提交(RC):在每一次执行快照读时生成ReadView。

    image-20210831105713952

    image-20210831105751871

    image-20210831110840565

    其实就是取当前版本链中最后一次提交的数据。

    可重复读(RR):仅在第一次执行快照读时生成ReadView,后续快照读复用(有例外:后面会说)。

    image-20210831111310645

    因为两次快照读使用相同的ReadView,所以可以实现可重复读。

    RR级别下使用MVCC能避免幻读吗?
    能,但不完全能!

    连续多次快照读,ReadView会产生复用,没有幻读问题
    特例:当两次快照读之间存在当前读,ReadView会重新生成,导致产生幻读

  • 相关阅读:
    oracle查询第几行到第几行的数据
    php/js将 CST时间转成格式化时间
    js获取当前时间:yyyy-MM-dd HH:MM:SS
    mysql 查询时间戳格式化 和thinkphp查询时间戳转换
    Java语言基础:运算符
    APP的三种开发模式
    架构图-模型
    Java语言基础:常量和变量
    APP开发之Dcloud简介
    APP开发
  • 原文地址:https://www.cnblogs.com/jiajun107/p/15222098.html
Copyright © 2011-2022 走看看