SQL - 事务隔离性问题 与 事务隔离级别 简述

  1. 概述

    1. 数据库 隔离性 相关问题
  2. 背景

    1. 这个算是每个 it 工作人员, 都应该有点理解吧
      1. 别人写过, 也不妨碍我理解认识啊...
    2. 说来惭愧
      1. 我之前对这些的认识, 其实很凌乱
        1. 本身就是为了应付面试, 硬背
        2. 理解上也没有层次
          1. 甚至把 事务特性, 和 隔离性问题 理解为 同一个层次 的东西
          2. 但实际上, 隔离性 相关的问题, 是 特性下面 的问题, 更加具体
          3. 估计没有人比我还笨了吧...

1. 隔离性 的问题

  1. 概述

    1. 隔离性的问题
  2. 背景

    1. 事务隔离性如果出了问题, 会让事务之间相互影响
      1. 可能还会导致很多 莫名其貌 的结果
    2. 最简单的问题
      1. 并发取钱
        1. 当然现实中这是不太可能的
  3. 问题们

    1. 脏读
    2. 不可重复读
    3. 幻读
  4. 解释

    1. ref 里提到了 可重复读, 我觉得这个不是问题, 所以我没有把它 单独列出来

1. 脏读

  1. 概述

    1. 脏读
  2. 脏读

    1. 事务中, 读取到 其他事务未提交 的改动
  3. 场景

    1. 事务

      1. 事务A
      2. 事务B
    2. 操作

      1. 针对 数据 D
    3. 行为

      1. 事务A 开启, 查询 D 值为 d1
      2. 事务B 开启, 修改 D 值为 d2
      3. 事务A 再次 查询 D, 值为 d2
      4. 事务B 再次 修改 D, 改为 d1
      5. 事务B 提交
      6. 事务A 再次 查询D, 值为 d1
    4. 问题

      1. 事务A 中间一次查询, 查的 D 的值为 d2
        1. 这个 d2, 是 事务B 修改所致
        2. 但是 事务B 实际上, 并没有最终提交
    5. 结果

      1. 事务A 可以读取到 其他事务 没有提交 的结果
        1. 这种结果本身很不稳定, 容易出现问题
        2. 而且这种问题, 甚至不太好复现...

2. 不可重复读

  1. 概述

    1. 不可重复读
  2. 不可重复读

    1. 事务中, 读取到 其他事务未提交 的改动
  3. 场景

    1. 事务

      1. 事务A
      2. 事务B
      3. 事务C
    2. 操作

      1. 针对 数据 D
    3. 行为

      1. 事务A 开启, 查询 D 值为 d1
      2. 事务B 开启, 修改 D 值为 d2, 并提交
      3. 事务A 再次 查询 D, 值为 d2
      4. 事务C 开启, 修改 D 改为 d3, 并提交
      5. 事务A 再次 查询D, 值为 d3
    4. 问题

      1. 事务A 的两次查询, 结果都不一样
        1. 一次是 事务B 的提交
        2. 一次是 事务C 的提交
      2. 我个人的理解
        1. 事务操作的数据, 应该是在这个事务开始运行时候的快照
        2. 如果其他事务要对相关数据修改, 就应该等着
        3. 等它改完了, 再按时间顺序排队继续
        4. 感觉这个比较理想化, 几乎就是 序列化 了...
    5. 结果

      1. 事务A 可以读取到 其他事务 提交 的修改
        1. 感觉 好像也没有比 脏读 好到哪里去
  4. 可重复读

    1. 事务中, 在自己没有修改的前提下, 对同一个值的读取, 每次结果都应该是一样的

3. 幻读

  1. 概述

    1. 幻读
  2. 幻读

    1. 事务中, 多次读取的结果, 会有一些偏差
      1. 读到 上次 不存在 的值
      2. 丢失 上次 存在的值
  3. 场景

    1. 事务

      1. 事务A
      2. 事务B
    2. 操作

      1. 按条件搜索
    3. 行为

      1. 事务A 开启, 查询值为 d1
      2. 事务B 开启, 插入值为 d2, 并提交
      3. 事务A 再次 查询, 值为 d1, d2
    4. 问题

      1. 事务A 的两次查询, 结果都不一样
        1. 第二次多了个 d2
        2. 这个 d2, 第一次不存在
    5. 结果

      1. 事务A 可以读取到 其他事务 提交的 插入/删除
        1. 感觉 好像也没有比 不可重复度 好到哪里去

2. 事务隔离级别

  1. 概述

    1. 事务隔离级别
  2. 背景

    1. 为了处理以上的问题, 有了事务隔离级别
      1. 技术上可能也不是一步到位
      2. 生产中可能会有不同的需求
      3. 性能方面, 也会有或多或少的牺牲
  3. 隔离级别

    1. 读未提交 - READ UNCOMMITTED
    2. 读已提交 - READ COMMITTED
    3. 可重复读 - REPEATABLE READ
    4. 序列化 - SERIALIZABLE
  4. 表格

    隔离级别 | 脏读 | 不可重复读 | 幻读

    • | - | - | - |
      读未提交 | O | O | O |
      读已提交 | X | O | O |
      可重复读 | X | X | O |
      序列化 | X | X | X |
  5. 其他

    1. mysql 的默认隔离级别, 是 可重复读
    2. 实际上 mysql 的 可重复读, 是解决了 幻读 问题的
      1. 但是这个表这么我先这么画, 主要是为了方便自己记忆
      2. 具体的机制, ref 的文章里, 讲得很清楚

ps

  1. ref

    1. 一文讲清楚MySQL事务隔离级别和实现原理,开发人员必备知识点

      1. 讲得很详细
        1. 表面的现象
        2. 实验来仔细探究, 而且思路简单科学
        3. 后面还提到了 b+树 机制, 当然这块我数据结构不太好, 就没看懂...
          1. 老实说, 挺丢人的...
    2. 以后别再说你不懂MySQL中的「幻读」了

      1. 另一篇专门讲 幻读 的文章
        1. 感觉条理清晰
        2. 但是我目前功力有限, 好些东西, 还理解不了
  2. 后续

    1. mvcc
    2. b+树
    3. 这个是 单点事务 的问题, 后续还有 分布式事务, 当然这个我只有等以后再查了
posted @ 2020-03-28 17:54  轩辕拾銉  阅读(202)  评论(0编辑  收藏  举报