首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试着理解MVCC

试着理解MVCC
EN

Stack Overflow用户
提问于 2019-09-01 13:54:35
回答 3查看 447关注 0票数 2

我在试着理解MVCC却无法理解它。例如。Transaction1 (T1)尝试读取某些数据行。在同一时间,T2更新同一行。

交易流程是

T1 begin -> T2 begin -> T2提交-> T1提交

因此,第一个事务获取数据库的快照,并返回用户结果,用户将根据该结果构建其他计算。但据我所知,客户会得到旧的数据价值吗?据我所知,在T1事务开始后,该事务不知道其他一些事务会更改数据。那么,如果现在的用户在那之后做一些计算(不涉及DB ),那么他是在错误的数据上进行计算吗?或者我说的不对,第一个事务有一些机制来知道该行被更改了吗?

现在让我们更改事务流。

T2beg -> T1beg -> T2com -> T1com

在2PL中,用户由于锁而获得更新版本的数据(T1必须等待独占锁释放)。但是在MVCC的情况下,它仍然是旧的数据,因为我理解postgresql模型。这样我就能得到陈旧的数据来换取速度。我说的对吗?还是我错过了什么?

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-09-02 05:33:12

是的,您可能会从数据库中读取一些旧数据(并发事务已经修改),在此基础上执行计算,并将“过时”数据存储在数据库中。

这不是一个问题,因为与发生事务的实际顺序不同,逻辑顺序更相关:

如果T1读取一些数据,那么T2修改数据,然后T1根据它读取的内容修改数据库,您可以说T1逻辑上发生在T2之前,并且没有不一致之处。

只有当T1和T2修改相同的数据时才会出现异常: T1读取数据,T2修改数据,然后T1根据读取的内容修改相同的数据。这种异常被称为“丢失的更新”。

丢失的更新只能在最弱的隔离级别(默认情况下)发生,即READ COMMITTED

如果希望更好地与并发活动隔离,则至少需要使用REPEATABLE READ隔离。然后,当T1试图更新数据时,它将收到一个序列化错误,您必须重复该事务。在第二次尝试中,它将读取新的数据,所有内容都将是一致的。

票数 6
EN

Stack Overflow用户

发布于 2019-09-01 14:38:27

事务流程是next T1 begin -> T2 begin -> T2提交-> T1提交。因此,第一个事务获取数据库的快照,并返回用户结果,用户将根据该结果构建其他计算。但据我所知,客户会得到旧的数据价值吗?

除非T1和T2试图更新同一行,否则通常可以将其重新排序为: T1 begin;T1 commit;T2 begin;T2 commit;

换句话说,T2在T1作出决策时更改数据可能会产生任何不良的业务结果,也可以通过T2在T1做出相同决定之后立即更改数据来实现。

票数 0
EN

Stack Overflow用户

发布于 2021-06-22 17:12:52

每个事务只能看到较年轻或等于该事务ID的数据。

当事务1读取数据时,它将该数据的读取时间戳标记为事务1。

如果事务2试图读取相同的数据,它将检查数据的读取时间戳,如果数据的读取时间戳小于事务2,则事务2将被中止,因为1<2--1在我们之前到达,它们必须在我们之前完成。

在提交时,我们还检查数据的读取时间戳是否小于提交事务。如果是,我们中止事务并使用新的事务ID重新启动。

我们还检查写时间戳是否少于我们的事务。年轻的交易获胜。

有一种边缘情况,如果较早的事务先于较年轻的事务,则较年轻的事务可以中止。

我实际上已经用Java实现了MVCC。(请参阅事务跑步者mvcc代码)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57746567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档