开两个MySQL连接,A的一个REPEATABLE READ事务里连续两次COUNT(*),中途B插入并提交了新数据,验证A是否会看到变化。
A开一个事务连续读两次,中途B插入并提交新数据。
操作时间线连接A: SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ 连接A: START TRANSACTION 连接A: SELECT COUNT(*) FROM t4 → 结果 3 连接B: INSERT INTO t4 (v) VALUES (100),(200) (B是autocommit,立刻提交) 连接B: SELECT COUNT(*) FROM t4 → 结果 5(B自己当然能看到自己刚插入的) 连接A: SELECT COUNT(*) FROM t4 → 结果?(同一个事务,第二次读)
B已经插入并提交了2行,A的事务还没提交。
结果A第一次读(B插入之前): 3 B插入并提交,B自己读: 5 A第二次读(同一事务,B已提交之后): 3 ← 跟第一次一样,没有变化! A commit() A开始新事务,读: 5 ← 提交之后,新事务才能看到
结果确认:A在同一个事务里两次读到的都是3,哪怕B已经插入并提交了新数据。只有A自己commit之后,开一个新事务重新读,才看到5。这就是REPEATABLE READ的行为——一个事务从它第一次读数据的那一刻起,就拿到了一份"快照",事务内所有后续的普通SELECT都基于这份快照,不管其他事务在这期间提交了什么。
每一步都是本文上面用两个MySQL连接跑出来的原始结果。