Oracle重新启动更新,在Postgresql中有类似的东西吗?

jdg4fx2g  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(117)

我正在阅读《Oracle Database Transactions and Locking Revealed》-第4章“Concurrency and Multiversioning”。在Oracle中,我们有Restart Update(Oracle将从头开始重新启动Update语句)。在Postgresql中有类似的东西吗?
Oracle示例:

Tx1: Update table set col1=0 (old value was col1=2);
<no commit>;
Tx2: Update table set col2=... where col1>0;
Tx1: commit;
Tx2: the update is restared by Oracle Database;

Here是一个链接,描述了“重新启动更新”的含义。

laik7k3q

laik7k3q1#

这种“重新启动的更新”似乎是Oracle处理READ COMMITTED隔离级别问题的方式,我们想要更新的行可能会在我们锁定它之前被并发事务修改。
PostgreSQL必须处理同样的问题,但它并没有通过从头开始完整的UPDATE语句来解决这个问题。相反,它只检索再次更改的行,检查它是否仍然满足WHERE条件,并使用更新的行进行进一步处理。
文档短语如下:
UPDATEDELETESELECT FOR UPDATESELECT FOR SHARE命令在搜索目标行方面的行为与SELECT相同:它们将只找到在命令开始时提交的目标行。但是,这样的目标行在被找到时可能已经被另一个并发事务更新(或删除或锁定)。在这种情况下,潜在的更新器将等待第一个更新事务提交或回滚(如果它仍在进行中)。[...]如果第一个更新器提交,如果第一个更新器删除了该行,则第二个更新器将忽略该行,否则它将尝试将其操作应用于该行的更新版本。将重新计算命令的搜索条件(WHERE子句),以查看行的更新版本是否仍与搜索条件匹配。如果是,则第二更新器使用行的更新版本继续其操作。
这种技术在PostgreSQL中的内部名称是“EvalPlanQual”。如果你想了解更多细节,我建议你阅读executor README中的相应部分。
Oracle这样做的方式看起来既费力又昂贵(重新计算整个语句),而PostgreSQL在重新计算那些已经更改的行时更有效。在缺点方面,PostgreSQL技术可能会导致令人惊讶的异常,如this article中所述。

相关问题