Postgres INSERT DO UPDATE并发问题

时间:2018-12-05 19:38:27

标签: postgresql concurrency upsert

假设我有一个简单的names表:

CREATE TABLE names(
    id SERIAL PRIMARY KEY,
    name TEXT,
    CONSTRAINT names_name_key UNIQUE (name)
);

我在多个线程中执行以下查询:

WITH ins AS (
   INSERT INTO names(name)
   VALUES ('bob')
   ON     CONFLICT ON CONSTRAINT names_name_key DO UPDATE
   SET    name = NULL
   WHERE  FALSE      -- never executed, but locks the row
   RETURNING id
   )
SELECT id FROM ins
UNION  ALL
SELECT id FROM names
WHERE  name = 'bob'  -- only executed if no INSERT
LIMIT  1;

此查询是否有可能不返回任何结果?我了解该查询将一直阻塞,直到执行此查询的其他事务提交或回滚为止,但是一旦其他事务提交,是否可以保证随后的SELECT语句能够看到该提交的事务?

示例是从以下SO线程复制的:Return rows from INSERT with ON CONFLICT without needing to update

更新:答案实际上是肯定的。打开两个Postgres会话,并按以下顺序执行查询:

线程A

BEGIN;
execute query;

线程B

BEGIN; 
execute query; 

现在注意 B 已被阻止,正在等待 A 提交或回滚。

线程A

COMMIT;

线程B 将解除阻止,然后不返回任何结果。

0 个答案:

没有答案