解决读后写竞争条件

Resolve write after read race condition

这是我需要帮助的竞争条件场景:

我们正在尝试在数据库中创建项目 A 和项目 B,并且我们希望保留项目 B 是项目 A 的“childOf”。我们假设请求创建项目 B 以及“childOf”关系数据在请求创建项目 A 之前到达。

以下是假设单个作业一次处理一个请求的步骤

如果同时有多个作业运行,则可能会出现竞争条件:

Process A Process B
req to create item B
check db for item A and item A is not found
req to create item A arrives and item A is created
since item A doesn't exist when it was checked last time, create a pending record in db with the relationship details
the pending record stays in the DB forever since item A is already created by process A while the pending record hasn't been inserted in the DB yet

如何解决此竞争条件?对不起,如果这太抽象了。如果我应该进一步详细说明,请告诉我。

我会创建一个“待定”对象,而不是作为一个单独的、不同的对象,而是在“真实”对象所在的地方,只是用一个标志来指示它的状态。

CREATE TABLE object (
   name varchar(100)
      CONSTRAINT object_pkey PRIMATY KEY,
   pending boolean DEFAULT FALSE NOT NULL
);

现在我将像这样添加一个常规对象:

INSERT INTO object (name)
VALUES ('A')
ON CONFLICT ON CONSTRAINT object_pkey
DO UPDATE SET pending = FALSE;

挂起的对象是这样插入的:

INSERT INTO onject (name, pending)
VALUES ('A', TRUE)
ON CONFLICT ON CONSTRAINT object_pkey
DO NOTHING;

那么你在添加对象之前不需要检查是否存在,竞争条件就没有了。 INSERT ... ON CONFLICT 被设计成原子性的并且没有竞争条件。