我是否需要更高的事务隔离才能使约束在 PostgreSQL 中可靠地工作?

Do I need higher transaction isolation to make constraints work reliably in PostgreSQL?

我有一个情况需要检查某行是否存在,如果存在则不再创建它。大致总结如下:

select id from table where constraintA= and constraintB=

紧接着在我的代码中:

if not exist
insert into table values (,, {other data})

为了确保约束是正确的,我可以制作一个像unique(constraintA,constraintB)这样的唯一索引。

但是,在 https://www.postgresql.org/docs/10/transaction-iso.html 中它说 Postgres 在行上使用锁,并且新创建的数据与其他并发事务隔离。所以他们不会互相阻止,因为我没有更新或删除数据。

这让我想到了我的问题,我是否需要高于 read committed 的隔离级别来确保正确性?如果不是,我的理解对吗?

PS: 我正在使用 Postgres 10.5

您的担心是对的,但您可以依靠数据库约束按预期工作,即使面对并发事务。

约束在 PostgreSQL 中作为特殊触发器实现,并且触发器函数涉及通过拍摄新快照来“破坏”MVCC,该快照也将看到未提交的行。

这不在常规文档中;对于这样的主题,文档在源代码中。参见 RI_Initial_Checksrc/backend/utils/adt/ri_triggers.c, particularly this part