【问题标题】:How to lock data in postgres the optimal way如何以最佳方式锁定postgres中的数据
【发布时间】:2021-09-01 19:34:19
【问题描述】:

我有这两个函数作为互斥锁和解锁:

CREATE OR REPLACE FUNCTION get_config (guildid_in int8, key_in varchar) RETURNS jsonb AS $$
    DECLARE d JSONB;
    BEGIN
        WHILE (SELECT locked FROM guild_options WHERE guildid = guildid_in AND key = key_in) LOOP END LOOP;
        UPDATE guild_options SET locked = true WHERE guildid = guildid_in AND key = key_in;
        SELECT data INTO d FROM guild_options WHERE guildid = guildid_in AND key = key_in ;
        REtURN d;
    END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION set_config (guildid_in int8, key_in varchar, data_in jsonb) RETURNS void AS $$
    BEGIN
        UPDATE guild_options SET locked = false, data = data_in WHERE guildid = guildid_in AND key = key_in;
    END;
    $$ LANGUAGE  plpgsql;

我有这两个功能的原因是因为我不希望不同客户端之间的数据竞争覆盖数据等等,这允许我锁定一条数据,修改它然后解锁以供其他客户端读取/更新.我没有使用 postgres 锁(表锁、行锁、咨询锁),因为我需要锁定多个事务的能力,并且因为我在程序中使用数据库池,所以我不能使用咨询锁,因为有多个会话一次连接到数据库,我无法控制哪一个锁定/解锁

有没有更好的方法来做到这一点(比如更好的轮询)?

【问题讨论】:

    标签: sql postgresql locks


    【解决方案1】:

    您“需要锁定多个事务的能力”。这正是 Postgres 锁的作用。可以在事务或会话级别获取建议锁。您可能还想查看Serializable Isolation Level
    顺便说一句:您的功能没有达到您的预期。在 get_config 中,您将锁定的列更新为 True,但 在您提交之前没有其他会话看到此内容。现在,如果此过程是更大且仅部分完成的事务的一部分,则此处的提交将提交到目前为止完成的所有事务,如果稍后整个事务失败,则您已提交事务的一部分。即使您在更新后提交,仍然有可能在更新和提交之间有另一个事务(slim 但不是 0)。 set_config 函数也是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-07
      相关资源
      最近更新 更多