louettagfh
2020-07-05 22:37:39 +08:00
你这个理解可能不太对
可重复读是事务隔离级别
你在文章里写的:
因为 session 1 执行 select * from t where id = 5 for share 之后,会拥有表级别的共享意向锁和 id 为 5 的那个索引记录的共享锁,所以 session 2 虽然获取到了表级别的独占意向锁,但是它无法获取到 id 为 5 的那个索引记录的独占锁。任何事务都不能够修改或删除 id 为 5 那行,因此保证了可重复读。
最后一句" 任何事务都不能够修改或删除 id 为 5 那行,因此保证了可重复读。" 这句表述的不对,一个事务可以有多条语句,s1 创建事务 t1 用 record lock 锁住了这条 record, 但它执行 t1 后面的语句时,这把 record lock 已经被放开了. 其他事务的是可以修改的 id 为 5 的 record.
MySQL 如何实现可重复读?
利用 MVCC
在 MySQL 中 MVCC 是 undo log + read view,依然以你的例子举例:
s1 创建事务 t1 时会创建 read view 即 r1,
s2 创建事务 t2 时会创建 read view 即 r2.
t1 第一次读 id=5 的 record 为 v1,
t2 修改 id=5 的 record 为 v2,
t1 再次读的时候会利用 read view 即 r1,判断 v2 是否可读,它会发现 v2 的 trx_no 大于 r1 的 trx_no, t1 就利用 undo log 回溯上一个版本即 v1. 这是可重复读.