bigywater.tech
MySQL / InnoDB · 15

READ COMMITTED:提交之后当前事务能否看见

把隔离级别切到READ COMMITTED,跑跟上一篇一模一样的两连接实验,看同一个事务里连续读到的结果这次是不是还保持不变。

3→5→6
READ COMMITTED下A事务内三次读的结果
每条SELECT一份快照
与REPEATABLE READ整个事务一份快照的区别
对照上一篇
同样的B插入序列,两种隔离级别结果完全不同

做的事:同样的两连接实验,只改隔离级别

上一篇REPEATABLE READ下,A的事务两次读到的是同一份快照;这次换成READ COMMITTED,跑同样的流程。

操作时间线连接A: SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED 连接A: START TRANSACTION 连接A: SELECT COUNT(*) FROM t4 → 结果 3 连接B: INSERT INTO t4 (v) VALUES (100),(200) (立刻提交) 连接A: SELECT COUNT(*) FROM t4 → 结果?(同一事务,第二次读) 连接B: INSERT INTO t4 (v) VALUES (300) (又提交一次) 连接A: SELECT COUNT(*) FROM t4 → 结果?(同一事务,第三次读)

验证:这次A的每一次读都跟着B的提交变化

对比上一篇REPEATABLE READ下A两次读都是3的结果。

结果A第一次读(B插入之前): 3 B第一次插入并提交(2行) A第二次读(同一事务,READ COMMITTED): 5 ← 变了!立刻看到B刚提交的 B第二次插入并提交(1行) A第三次读(同一事务): 6 ← 又变了,再次看到B新提交的

同样是"同一个事务里连续读三次",READ COMMITTED下每一次都拿到最新的已提交数据:3 → 5 → 6,跟着B的两次提交同步变化。而上一篇REPEATABLE READ下,同样的操作序列,A的读取结果全程停在3,直到A自己提交。

两种隔离级别的区别就在这里:快照的生效范围不同。REPEATABLE READ给一个事务从第一次读开始就锁定一份快照,事务内全程有效;READ COMMITTED则是每一条SELECT语句单独生成一份新快照,只要别的事务已经提交,下一条SELECT立刻就能看到。这也是为什么READ COMMITTED下,同一个事务里两次读同一行数据可能得到不同结果(这种现象叫"不可重复读"),而REPEATABLE READ天生就不会有这个问题。

分步演示:READ COMMITTED的快照粒度

每一步都是本文上面用两个MySQL连接跑出来的原始结果,与上一篇REPEATABLE READ的结果形成对照。

READ COMMITTED下,同一事务的每次读都是新快照
这一步新验证的读取

    本文用到的工具

    • 本机 MySQL 26.7.0(InnoDB),SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
    • pymysql 开两个独立连接模拟A、B两个并发会话
    京ICP备2026067502号-1京公网安备11010502063487号