[英]Is INSERT ... SELECT an atomic transaction?
我使用这样的查询:
INSERT INTO table
SELECT * FROM table2 t2
JOIN ...
...
WHERE table2.date < now() - '1 day'::INTERVAL
FOR UPDATE OF t2 SKIP LOCKED
ON CONFLICT (...)
DO UPDATE SET ...
RETURNING *;
我的问题是关于FOR UPDATE t2 SKIP LOCKED
。 我应该在这里使用它吗? 或者 Postgres 会使用INSERT SELECT ON CONFLICT
自动锁定这些行直到事务结束?
我的目标是防止其他应用程序(同时)使用内部SELECT
捕获已被此应用程序捕获的行。
是的, FOR UPDATE OF t2 SKIP LOCKED
是使用默认的Read Committed事务隔离防止竞争条件的正确方法。
添加的SKIP LOCKED
还可以防止死锁。 请注意,竞争事务可能每个都从SELECT
获得部分集 - 无论它可以先锁定。
虽然 Postgres 中的任何事务都是原子的,但它不会阻止另一个(也是原子的)事务选择(并插入 - 或至少尝试)同一行,因为没有FOR UPDATE
SELECT
不会使用排他锁。
事务被称为原子事务:从其他事务的角度来看,它要么完全发生,要么根本不发生。
有关的:
说明:
像INSERT
这样的 SQL DML 命令总是自动原子的,因为它不能在事务之外运行。 但是你不能说INSERT
是一个事务。 错误的术语。
在 Postgres 中,所有锁都保留到当前事务结束时释放。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.