📊 数据库相关
一、什么是事务(Transaction)
https://chatgpt.com/share/694a9c6b-1b88-8011-9f39-7a1422727c74
事务是一组操作的集合,这组操作要么 全部成功,要么 全部失败回滚。
典型例子(转账):
A 扣 100 B 加 100
如果只扣了 A,没有给 B 加钱 —— 灾难
事务就是为了防止这种「中间态」被系统看到。
二、ACID 是哪四个?
A C I D = Atomicity / Consistency / Isolation / Durability
这四个是数据库对事务的承诺。
三、Atomicity(原子性)——要么全做,要么全不做
1️⃣ 定义
事务中的操作 不可再分:
-
成功:所有操作生效
-
失败:所有操作撤销
2️⃣ 举例
BEGIN; UPDATE account SET balance = balance - 100 WHERE id = 'A'; UPDATE account SET balance = balance + 100 WHERE id = 'B'; COMMIT;
如果中途宕机:
-
A 已扣钱
-
B 还没加钱
➡️ 原子性要求:两步都回滚
3️⃣ 怎么实现?(核心:Undo Log)
数据库会记录:
A 原来是 1000
如果事务失败:
回滚:A = 1000
👉 Undo Log = 回退日志
4️⃣ 关键点(很多人混淆)
❌ 原子性 ≠ 一条 SQL
✔️ 原子性是 一个事务的多条操作
四、Consistency(一致性)——数据永远合法
1️⃣ 定义
事务前后,数据库从一个合法状态 → 另一个合法状态
一致性更多是「业务 + 约束」层面的
2️⃣ 举例
不变量(Invariant):
A.balance + B.balance = 常量
事务执行前后,这个条件必须成立。
3️⃣ 谁来保证一致性?
这是一个共同责任:
| 层级 | 责任 |
|---|---|
| 数据库 | 外键 / NOT NULL / CHECK |
| 应用 | 业务逻辑正确 |
| 事务 | 保证中间状态不暴露 |
📌 一致性不是数据库“自动送的”
4️⃣ 常见误解
❌ “有 ACID 就一定一致”
✔️ 你业务写错,照样不一致
五、Isolation(隔离性)——事务互不干扰
这是 最复杂、最重要、面试最爱问 的部分。
1️⃣ 定义
并发事务执行时:
一个事务 看不到 另一个事务的中间状态
2️⃣ 如果没有隔离性会怎样?
并发问题三件套:
❌ 脏读(Dirty Read)
读到 未提交的数据
❌ 不可重复读(Non-repeatable Read)
同一事务内,两次读结果不一样
❌ 幻读(Phantom Read)
多了一行 / 少了一行(范围变化)
3️⃣ SQL 标准的 4 种隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| Read Uncommitted | ❌ | ❌ | ❌ |
| Read Committed | ✅ | ❌ | ❌ |
| Repeatable Read | ✅ | ✅ | ❌ |
| Serializable | ✅ | ✅ | ✅ |
实际中 MySQL 默认 Repeatable Read
PostgreSQL 默认 Read Committed
4️⃣ 怎么实现隔离?(核心)
🔒 锁(Lock)
-
行锁 / 表锁
-
排他锁 / 共享锁
🕰 MVCC(多版本并发控制)
-
每行多个版本
-
读的是「历史快照」
📌 现代数据库几乎都靠 MVCC + 少量锁
5️⃣ 工程视角
-
隔离级别越高 → 性能越差
-
大多数系统 不会用 Serializable
六、Durability(持久性)——提交就不会丢
1️⃣ 定义
事务一旦提交:
即使 宕机 / 断电 / 崩溃,数据也不会丢
2️⃣ 怎么实现?(核心:Redo Log / WAL)
顺序写日志:
UPDATE A = 900
然后才写磁盘数据页。
崩溃后:
- 通过 Redo Log 重放
3️⃣ 现实中的取舍
很多数据库允许:
commit 但日志还没真正落盘
➡️ 换性能
➡️ 牺牲一点点持久性
七、ACID 之间的关系(重点)
| 属性 | 关注点 |
|---|---|
| A | 回滚 |
| C | 业务正确 |
| I | 并发 |
| D | 崩溃 |
📌 Isolation 最复杂
📌 Consistency 最容易被误解
八、现实世界的“ACID 不完整”
1️⃣ 分布式系统
-
CAP 冲突
-
2PC / Saga / TCC
2️⃣ NoSQL
-
常见是 BASE
-
最终一致性
九、你在项目里该怎么用 ACID?(实战建议)
✅ 什么时候必须事务
-
钱
-
库存
-
状态机迁移
⚠️ 注意事项
-
事务尽量 短
-
不要在事务里:
-
网络请求
-
长时间计算
-
十、一句话总结(送你背)
ACID 是数据库对事务的四个承诺:
-
A:失败能回滚
-
C:前后都合法
-
I:并发不互相干扰
-
D:提交就不会丢