我在试着理解MVCC却无法理解它。例如。Transaction1 (T1)尝试读取某些数据行。在同一时间,T2更新同一行。
交易流程是
T1 begin -> T2 begin -> T2提交-> T1提交
因此,第一个事务获取数据库的快照,并返回用户结果,用户将根据该结果构建其他计算。但据我所知,客户会得到旧的数据价值吗?据我所知,在T1事务开始后,该事务不知道其他一些事务会更改数据。那么,如果现在的用户在那之后做一些计算(不涉及DB ),那么他是在错误的数据上进行计算吗?或者我说的不对,第一个事务有一些机制来知道该行被更改了吗?
现在让我们更改事务流。
T2beg -> T1beg -> T2com -> T1com
在2PL中,用户由于锁而获得更新版本的数据(T1必须等待独占锁释放)。但是在MVCC的情况下,它仍然是旧的数据,因为我理解postgresql模型。这样我就能得到陈旧的数据来换取速度。我说的对吗?还是我错过了什么?
谢谢
发布于 2019-09-02 05:33:12
是的,您可能会从数据库中读取一些旧数据(并发事务已经修改),在此基础上执行计算,并将“过时”数据存储在数据库中。
这不是一个问题,因为与发生事务的实际顺序不同,逻辑顺序更相关:
如果T1读取一些数据,那么T2修改数据,然后T1根据它读取的内容修改数据库,您可以说T1逻辑上发生在T2之前,并且没有不一致之处。
只有当T1和T2修改相同的数据时才会出现异常: T1读取数据,T2修改数据,然后T1根据读取的内容修改相同的数据。这种异常被称为“丢失的更新”。
丢失的更新只能在最弱的隔离级别(默认情况下)发生,即READ COMMITTED。
如果希望更好地与并发活动隔离,则至少需要使用REPEATABLE READ隔离。然后,当T1试图更新数据时,它将收到一个序列化错误,您必须重复该事务。在第二次尝试中,它将读取新的数据,所有内容都将是一致的。
发布于 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做出相同决定之后立即更改数据来实现。
发布于 2021-06-22 17:12:52
https://stackoverflow.com/questions/57746567
复制相似问题