我正在阅读《Oracle 数据库事务和锁定揭晓》一书 - 第 4 章“并发和锁定” 多版本控制”。在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;
这里是一个描述“重新启动更新”含义的链接。
这种“重启更新”似乎是 Oracle 处理这个问题的方式:在
READ COMMITTED
隔离级别下,我们想要更新的行可能会被锁定,当锁被释放时,该行可能已经被并发修改了。
PostgreSQL 必须处理同样的问题,但它并没有通过从头开始完整的
UPDATE
语句来解决它。相反,它仅再次检索它正在等待的行,检查它是否仍然满足 WHERE
条件并使用更新后的行进行进一步处理。
文档短语如下:
、UPDATE
、DELETE
和SELECT FOR UPDATE
命令在搜索目标行方面与SELECT FOR SHARE
相同:它们只会查找截至命令开始时间已提交的目标行。然而,这样的目标行在被发现时可能已经被另一个并发事务更新(或删除或锁定)。在这种情况下,潜在的更新程序将等待第一个更新事务提交或回滚(如果仍在进行中)。 [...] 如果第一个更新程序提交,则第二个更新程序将忽略第一个更新程序删除的行,否则它将尝试将其操作应用于该行的更新版本。重新评估命令的搜索条件(WHERE 子句),以查看该行的更新版本是否仍然与搜索条件匹配。如果是这样,第二个更新器将使用该行的更新版本继续其操作。SELECT
该技术在 PostgreSQL 中的内部名称为“EvalPlanQual”。如果您想了解更多详细信息,我建议您阅读executor README中的相应部分。