Bohr-L Bohr-L
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

刘博

I'm a slow walker, But I never walk backwards.
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 数据处理与存储类

  • Spring 生态类

  • 缓存问题类

  • 多线程类

  • JVM 类

  • MySQL 类

    • MySQL 为什么一定要有一个主键
    • MySQL 中的 RR 隔离级别,到底有没有解决幻读问题
    • MySQL 的行级锁到底锁的是什么东西?
    • 存储 MD5 值应该用 VARCHAR 还是用 CHAR?
    • 数据库的三范式是什么?
    • 说说 InnoDB 与 MyISAM 的区别
    • drop、truncate、delete 的区别
    • 聊一聊数据库事务机制
      • 聊一聊 MySQL 中的关联查询
      • 事务隔离级别有哪些?MySQL 的默认隔离级别是什么
      • 分库分表之后,id 主键如何处理?
      • 说说在 MySQL 中一条查询 SQL 是如何执行的?
      • 讲解下 DDL、DML、DCL
      • 存储过程和触发器的作用
      • MySQL 如何行转列和列转行
      • 如何查看 SQL 的执行计划
      • union 和 unionAll 的区别
      • having 和 where 的区别
      • 常见的索引原则
      • MySQL 中的 IN 和 EXISTS 子句有什么区别?
      • MySQL 如何处理 NULL 值,对性能有什么影响?
      • 如何在 MySQL 中处理和避免全表扫描?
      • MySQL 中的表空间是什么,它的作用是什么?
      • 在 MySQL 中,如何优化 ORDER BY 查询?
    • Java 8 + 特性类

    • 其他技术类

    • 常见面试题
    • MySQL 类
    刘博
    2025-12-29
    目录

    聊一聊数据库事务机制

    # 题)

    多个事务并发执行时,若缺乏隔离机制,会出现 3 类数据异常:

    • 脏读(Dirty Read):事务 A 读取到事务 B 未提交的修改数据,若事务 B 回滚,事务 A 读取的是 “脏数据”;
      • 示例:事务 B 修改用户余额为 200 元(未提交),事务 A 读取到 200 元,事务 B 回滚后,用户余额实际为 100 元,事务 A 读取的 200 元是脏数据。
    • 不可重复读(Non-Repeatable Read):事务 A 多次读取同一数据,事务 B 在期间修改并提交该数据,导致事务 A 多次读取结果不一致;
      • 示例:事务 A 第一次读取用户余额为 100 元,事务 B 修改并提交为 200 元,事务 A 再次读取为 200 元,两次结果不一致。
    • 幻读(Phantom Read):事务 A 多次查询同一范围数据,事务 B 在期间插入 / 删除该范围数据并提交,导致事务 A 多次查询的结果集行数不一致;
      • 示例:事务 A 第一次查询 “age>20” 的用户有 10 行,事务 B 插入 1 行并提交,事务 A 再次查询有 11 行,结果集行数变化。

    # 3. 事务隔离级别(解决并发异常的方案)

    MySQL 定义了 4 种隔离级别,从低到高依次为:

    隔离级别 脏读 不可重复读 幻读 实现原理(InnoDB)
    读未提交(Read Uncommitted) 允许 允许 允许 无锁,直接读取最新数据
    读已提交(Read Committed) 禁止 允许 允许 MVCC(每次查询生成新 read_view)
    可重复读(Repeatable Read) 禁止 禁止 禁止(默认) MVCC(事务内共用一个 read_view)+ 间隙锁
    串行化(Serializable) 禁止 禁止 禁止 表级锁,事务串行执行
    • 默认隔离级别:MySQL 默认隔离级别为 “可重复读(RR)”,InnoDB 通过 MVCC 和间隙锁解决所有并发异常;
    • 隔离级别与性能:隔离级别越高,并发性能越低(如串行化隔离级别下,事务需排队执行),需根据业务场景选择(如金融交易选 RR 或串行化,普通查询选 RC)。

    # 4. 事务的实现机制(InnoDB)

    InnoDB 通过 “日志机制” 和 “锁机制” 实现事务的 ACID 特性:

    • (1)原子性与回滚:undo 日志:
      • undo 日志记录事务执行前的数据状态(如修改前的余额为 100 元);
      • 若事务执行失败(如抛出异常),InnoDB 通过 undo 日志回滚数据(将余额恢复为 100 元)。
    • (2)持久性:redo 日志:
      • redo 日志记录事务执行后的修改操作(如将余额从 100 元改为 200 元);
      • 事务提交时,InnoDB 先将 redo 日志写入磁盘(“日志先行” 原则),再修改内存中的数据;
      • 即使数据库崩溃,重启后可通过 redo 日志重放修改操作,确保数据持久化。
    • (3)隔离性:MVCC 与锁机制:
      • MVCC 通过多版本数据实现 “读不加锁”,避免脏读和不可重复读;
      • 锁机制(行锁、间隙锁)避免并发写操作冲突,解决幻读。
    • (4)一致性:ACID 的最终目标:
      • 原子性、隔离性、持久性共同确保一致性(如转账操作要么全部成功,要么全部失败,且并发执行时数据不混乱);
      • 此外,业务逻辑(如 “余额不能为负”)也需通过约束(如 CHECK 约束)或代码确保一致性。

    # 5. 事务的常用操作

    -- 1. 开启事务(默认自动提交关闭)
    START TRANSACTION; -- 或 BEGIN;
    
    -- 2. 执行事务操作(如转账:扣除A的余额,增加B的余额)
    UPDATE user SET balance = balance - 100 WHERE id = 1; -- A扣100
    UPDATE user SET balance = balance + 100 WHERE id = 2; -- B加100
    
    -- 3. 提交事务(修改持久化)
    COMMIT;
    
    -- 4. 若操作失败,回滚事务(恢复到事务开始前状态)
    -- ROLLBACK;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    #


    上次更新: 12/30/2025
    drop、truncate、delete 的区别
    聊一聊 MySQL 中的关联查询

    ← drop、truncate、delete 的区别 聊一聊 MySQL 中的关联查询→

    最近更新
    01
    CPU 使用率较高排查和解决
    12-29
    02
    JVM OOM 问题如何排查和解决
    12-29
    03
    接口防刷怎么实现?
    12-29
    更多文章>
    Theme by Vdoing | Copyright © 2025-2026 Bohr-L's note
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式