暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL 中 Read View 的使用场景与原理

架构经纬 2024-08-27
286

在MySQL的InnoDB存储引擎中,Read View 是一种用于实现事务隔离级别的机制。本文将探讨 Read View 在不同事务隔离级别下的应用方式,以及它如何影响数据的一致性和可见性。

Read View 的作用

Read View 主要应用于 Repeatable Read (RR) 和 Read Committed (RC) 两种事务隔离级别中,以决定哪些数据对事务可见。而在 Read Uncommitted (RU) 和 Serializable 两种隔离级别下,则不需要使用 Read View。

Read Uncommitted (RU)

特点:允许事务读取未提交的数据,即发生脏读。原因:无需通过 Read View 来限制数据的可见性范围,事务可以自由读取其他事务未提交的数据。

Serializable

特点:提供最高级别的隔离性,确保每次读取都能看到一致的快照。原因:使用锁机制来保证事务之间的串行执行,不需要 Read View 来判断可见性。

RC 和 RR 下的 Read View

RC (Read Committed)生成时机:每次 SELECT 数据前都生成一个新的 Read View。效果:每次查询时都基于最新的数据生成 Read View,因此每次查询可能看到不同的数据版本。RR (Repeatable Read)生成时机:只在第一次读取数据时生成一个 Read View,之后复用同一个 Read View。效果:确保在同一个事务内多次查询同一数据时看到相同的结果,即重复读。

举例说明

假设有一个表 users,包含 id 和 name 字段。初始状态下,表中有一条记录 id=1, name="小明"。现在有三个事务 A、B、C 按照以下顺序执行:


事务A(事务ID: 100)事务B(事务ID: 200)事务C(事务ID: 300)
T1begin

T2
beginbegin
T3update user set name="小王" where id=1

T4update user set name="小红" where id=1
select * from user where id = 1
T5commitupdate user set name="小黑" where id=1
T6
update user set name="小白" where id=1select * from user where id = 1
T7
commit
T8

select * from user where id = 1
T9

commit
T10


RC 下的 Read View

事务A 将 name 修改为 "小红"。事务B 将 name 修改为 "小白"。事务C 读取 name 的值。RC 下的 Read ViewT4时刻:事务A 和 事务B 都还未提交,此时事务C 读取数据。根据可见性原则,事务C 最终看到的 name 值为 "小明"。T6时刻:事务A 提交,事务C 再次读取数据。此时会生成新的 Read View,根据可见性原则,事务C 最终看到的 name 值为 "小红"。T8时刻:事务B 提交,事务C 再次读取数据。再次生成新的 Read View,根据可见性原则,事务C 最终看到的 name 值为 "小白"。RR 下的 Read ViewT4时刻:与 RC 情况一致,事务C 最终看到的 name 值为 "小明"。T6时刻:事务C 再次读取数据,但 RR 会复用之前的 Read View,因此事务C 仍看到 name 值为 "小明"。T8时刻:事务C 再次读取数据,继续复用之前的 Read View,事务C 仍看到 name 值为 "小明"。

总结通过以上例子可以看出,在 RC 隔离级别下,由于每次查询都会生成新的 Read View,因此可以看到最新的已提交数据。而在 RR 隔离级别下,由于复用了初次查询时生成的 Read View,因此事务内多次查询同一数据时看到的结果始终一致。

这篇文章简洁明了地介绍了 Read View 在不同事务隔离级别下的工作原理,并通过实例帮助读者更好地理解其在实际场景中的应用。希望对您有所帮助!如果需要进一步调整,请随时告知。



文章转载自架构经纬,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论