📄 一句话概括
COMMIT 是事务的交付键:BEGIN 之后所有操作都停在「草稿区」,按下 COMMIT 的一刻一次性转正——转正之前外面看不见,转正之后断电也不丢。
📝 本节和前面几节的关系
上一节搭好了事务三件套的架子,本节把 COMMIT 这枚键单独看清:它标记的「生效边界」是什么、生效前后世界有什么不同。下一节 ROLLBACK 是它的反面镜像。
一、COMMIT 前后的两个世界
| COMMIT 前 | COMMIT 后 | |
|---|---|---|
| 自己看 | 能看到改动 | 能看到改动 |
| 别人(其他连接)看 | 还是旧数据 | 新数据 |
| 断电/崩溃 | 改动作废 | 改动保住 |
「一次性转正」意味着中间状态从未对外存在过——要么旧世界,要么新世界。
二、写法与流程
BEGIN;
INSERT INTO orders VALUES (1, '甲', 99.00); -- 草稿
UPDATE stock SET num = num - 1 WHERE goods = 'A'; -- 草稿
COMMIT; -- 一起转正
下单场景:订单表插一条、库存表减一个——两步捆住,COMMIT 一按,要生一起生。
三、COMMIT 的三个承诺
- 原子:BEGIN 后的每一条操作同批转正,绝不出现「插入了订单但没扣库存」
- 可见:COMMIT 后其他连接立刻(或下一个查询起)看到新数据
- 持久:数据库已把改动落到磁盘日志,之后断电、崩溃都不丢(ACID 的 D)
四、动手 Demo:肉眼看见「边界」
CREATE TABLE t (n INT);
INSERT INTO t VALUES (1); -- 未开事务,直接生效
BEGIN;
INSERT INTO t VALUES (2); -- 草稿
SELECT * FROM t; -- 自己看:1、2 都在
-- (想象此刻另一窗口 SELECT:只见 1,不见 2)
COMMIT;
-- 此刻起,所有窗口都能看到 2
在线 SQLite 运行器通常单连接,「另一窗口」想象一下即可;本机装环境时可双开验证。
五、30 秒实验
BEGIN;
INSERT INTO t VALUES (3);
ROLLBACK; -- 故意不 COMMIT
SELECT * FROM t; -- 没有 3
不 COMMIT 就撤销,草稿全废——COMMIT 是草稿转正的唯一通道。
六、常见误区
- 「INSERT 执行完就落库了」:事务里执行完只是进了草稿区;没 COMMIT 的都可能被撤销
- 「COMMIT 很慢,能省则省」:恰恰相反,COMMIT 是把缓存批量落盘的高效动作;真正慢的是没事务保护下的事后修数据
自测三问
1. COMMIT 前别人能看到你的改动吗?(不能,草稿区对外不可见) 2. COMMIT 之后断电会丢吗?(不会,已持久化) 3. 事务里不 COMMIT 直接 SELECT 能看到自己的改动吗?(能——只有自己看得见)- ☐ 下一节(4-16 回滚-取消一组已经执行的处理)
相关笔记
- 事务-集中执行无法分割的处理 —— 上一节:三件套全貌
- 回滚-取消一组已经执行的处理 —— 下一节:镜像的另一面
- AUTO_INCREMENT-自动输入连续的编号 —— 回滚留下的编号空洞
- 🗄️ 数据库基础 · 索引 —— 全课路线图