繁体   English   中英

INSERT ... SELECT 是原子事务吗?

[英]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不会使用排他锁

关于事务Postgres 手册

事务被称为原子事务:从其他事务的角度来看,它要么完全发生,要么根本不发生。

有关的:


说明:

  • INSERT这样的 SQL DML 命令总是自动原子的,因为它不能在事务之外运行。 但是你不能说INSERT一个事务。 错误的术语。

  • 在 Postgres 中,所有锁都保留到当前事务结束时释放。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM