CSNotesCSNotes
TODO
数据库
Java
SSM
React
学习路线
分布式
Redis
实用工具
GitHub
TODO
数据库
Java
SSM
React
学习路线
分布式
Redis
实用工具
GitHub
  • 第一阶段 SQL 语法与使用

    • 一、MySQL 语法基础
    • 二、多表查询与笛卡尔积
    • 三、JOIN 类型与算法
    • 四、LIKE 通配符与正则
    • 五、GROUP BY/HAVING /窗口函数
    • 六、字段类型与选型
    • 七、约束、主键与 DDL 语法
  • 第二阶段 SQL 执行与优化

    • 一、一条建表语句是如何执行的?
    • 二、EXPLAIN 执行计划
  • 第三阶段 数据存储结构(MyDB 轮子核心)

    • 一、字符集与 CHAR/VARCHAR 存储
    • 二、最大行大小 65535 bytes
    • 三、为什么 VARCHAR 上限是 16383?
    • 四、表、页与 Page Header 概念
    • 五、InnoDB 行格式 COMPACT
    • 六、磁盘空间管理器
  • 第四阶段 索引与数据结构

    • 一、为什么是 B+ 树?
    • 二、B+ 树插入、分裂、合并的完整过程
    • 三、容量计算:一颗高度为 3 的 B+ 树能存多少条数据?
    • 四、索引分类(聚簇/二级/联合/覆盖)
    • 五、联合索引 + 最左匹配原则
    • 六、索引失效 7 大场景
    • 七、索引创建策略:三星索引法
  • 第五阶段 事务、MVCC 与并发控制

    • 一、事务
    • 二、事务的本质(内核视角)
    • 三、MVCC 多版本快照读
    • 四、死锁四条件
    • 五、一条 INSERT 语句背后在干吗?
  • 第六阶段 预写日志 WAL 与崩溃恢复

    • 一、预写日志 WAL(Redo/Undo)
  • 第七阶段 数据建模与范式

    • 一、数据建模范式(入门版)
    • 二、数据建模范式(进阶版)
  • 第八阶段 数据库概念全景

    • 一、数据库/DBMS/SQL 全景定义
  • 第九阶段 常见面试题专题(占位:待补)

一、事务

(一)事务的定义

需要保证原子性、隔离性、一致性和持久性的一个或多个数据库操作称为事务。

(二)为什么要有事务?

现实世界的业务场景需要映射到数据库世界,而现实世界中的一次状态转换需要满足下面几种特性:

(三)事务的四大特性

原子性:事务作为一个整体被执行,其中的操作要么都做,要么都不做。

一致性:事务执行前后,数据库处于合法的状态。

隔离性:多个事务并发执行时,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能相互干扰。

持久性:事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

(四)原子性(Atomicity)

拿转账作例子:

转账只有两种状态:要么转了,要么没转。这种规则叫做原子性。

(五)隔离性(Isolation)

现实世界中,两种状态转换应该是互不影响的。让一些操作执行完了,再让另一些操作执行。

(六)一致性(Consistency)

数据库中的数据符合所有现实世界的约束,比如红绿灯只有三种颜色,房价不能为负的。比如建立主键,唯一索引,外键等。

(七)持久性(Durability)

一个状态转换完成后,这个转换的结果将永久保存。

事务状态.drawio
事务状态.drawio

可以看到,事务处于“提交的”或者“中止的”时候,事务结束。“中止的”代表数据库数据没有变化,“提交的”说明数据库变动刷新到磁盘了。

(八)并发事务会出现什么问题?

1. 脏读

读到了另一个事务未提交的数据。

脏读.drawio
脏读.drawio

2. 不可重复读

在一个事务多次读取同一个数据,如果读到的数据不一样,那么就出现了不可重复读现象

不可重复读.drawio
不可重复读.drawio

3. 幻读

幻读

The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.

所谓的幻读,就是在一个事务中,同一个查询,在不同的时间返回不同的结果集

幻读是针对数量,某一个事务多次查询记录数据,查到的数据不一样。就叫幻读。

(九)四种隔离级别

  • 读未提交:一个事务还没提交,就能被其他事务看到
  • 读提交:一个事务提交之后,才能被其他事务看到
  • 可重复读:一个事务执行过程中看到的数据,一直和这个事务启动时看到的数据一致
  • 串行化:对记录加读写锁,多个事务对这条记录进行读写操作时,如果发生读写冲突,后访问的事务必须等前一个事务执行完成,才能继续执行。

4 种隔离级别用来解决 3 个问题

读提交能解决脏读

可重复读能解决脏读、不可重复读

(十)事务的四种隔离级别

串行化(SERIALIZABLE):当串行化事务读取某些数据后,这些数据将不能被其他事务更改,但可以被读取,直到本事务结束。

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE ;
START TRANSACTION ;
SELECT * FROM TIME WHERE A = 1;
DO SLEEP(7);
COMMIT;
SELECT * FROM TIME WHERE A='1';
UPDATE TIME SET B='1000' WHERE A='1';
SELECT '已将B设为1000'

可重复读(REPEATABLE READ):串行化读取数据后,会阻止其他事务更改这些数据,而可重复读允许其他事务修改数据,但不可见。

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION ;
SELECT * FROM TIME WHERE A = 1;
DO SLEEP(7);
SELECT * FROM TIME WHERE A = 1;
COMMIT;
UPDATE TIME SET B='1000' WHERE A='1';

读已提交:在读已提交事务中,你可以读取到,其他事务对数据已经提交的更改,但会忽视其他事务未提交的更改,以确保读取的数据的合理性。

比如,某个用于修改用户姓名的事务,当用户姓名合理时,该事务提交,不合理时,事务将执行回滚。我们可以使用读已提交事务,只读取上述事务提交的更改,以确保读取到的用户姓名始终是合理的。

SET SESSION TRANSACTION ISOLATION LEVEL  READ COMMITTED ;
START TRANSACTION ;
SELECT B FROM TIME WHERE A = 1;
COMMIT;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION ;
UPDATE TIME SET B=1000 WHERE A=1;
SELECT 'B设为1000';
DO SLEEP(7);

COMMIT ;

读未提交:

SET SESSION TRANSACTION ISOLATION LEVEL  READ UNCOMMITTED ;
START TRANSACTION ;
SELECT B FROM TIME WHERE A = 1;
COMMIT;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION ;
UPDATE TIME SET B=1000 WHERE A=1;
SELECT 'B设为1000';
DO SLEEP(7);

ROLLBACK ;

一个事务可能会对应多个数据项,所以它会锁住很多数据。

什么叫事务?

在 insert、delete、update 都会产生事务

编辑此页
上次更新: 2026/9/18 20:24
Next
二、事务的本质(内核视角)