假设我有一个简单的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 将解除阻止,然后不返回任何结果。