【问题标题】:Locking the 'select' in update ... from select - postgresql在更新中锁定“选择”......来自选择 - postgresql
【发布时间】:2021-07-21 17:56:12
【问题描述】:

我有一些继承代码如下:

const sql = `UPDATE fqdn SET lock = $1
                    FROM (SELECT id FROM fqdn WHERE region = $2 AND lock IS NULL AND expires < $3 OR lock = $1 LIMIT $4) AS expired
                    WHERE fqdn.id = expired.id
                    RETURNING fqdn.id, fqdn.config, fqdn.data`;

有多个微服务在同一个数据库上运行该查询。 创建者的想法是使用一个锁定字段来锁定每个微服务要处理的这批行,该锁定字段是运行微服务的机器的 fqdn ($1 => fqdn)。

看起来虽然有时两个微服务最终会在同一个批次上工作。 有没有办法对其进行序列化,以便并发的第二个线程仅在第一个线程完成更新锁后才执行选择?

谢谢

【问题讨论】:

    标签: sql postgresql concurrency locking


    【解决方案1】:

    查询中确实存在竞争条件。两个并发执行可以在子查询中找到同一行,虽然其中一个更新会阻塞,但它最终会在另一个事务完成后继续处理。

    您应该在子查询中添加以下内容:

    FOR NO KEY UPDATE SKIP LOCKED
    

    这将保证没有两个查询可以返回相同的行。

    【讨论】:

    • 谢谢 Laurenz,看起来效果不错
    猜你喜欢
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 2013-09-25
    相关资源
    最近更新 更多