当前位置: 首页 > 知识库问答 >
问题:

如何在postgres中锁定数据的最佳方式

端木宏盛
2023-03-14

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

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锁(表锁、行锁、咨询锁),因为我需要锁定多个事务的能力,而且因为我在程序中使用数据库池,所以我不能使用咨询锁,因为同时有多个会话连接到数据库,我无法控制哪一个锁/解锁

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

共有1个答案

宗政楚
2023-03-14

您“需要锁定多个事务的能力”。这正是Postgres锁的作用。可以在事务或会话级别获取咨询锁。您可能还希望将其视为可序列化隔离级别
顺便说一句:你的功能没有达到你的预期。在<code>get_config</code>中,您将锁定列更新为True,但在提交之前,其他会话都看不到这一点。现在,如果这个过程是一个大得多且仅部分完成的事务的一部分,那么这里的提交将提交到目前为止所做的所有事情,如果整个事务稍后失败,那么您已经提交了事务的一个部分。即使您在更新后提交,在更新和提交之间仍有可能发生另一个事务(很小,但不是0)。这同样适用于set_config函数。

 类似资料:
  • 我正在尝试为我正在处理的行设置,直到下一次提交: 我认为应该发生的是,如果两个线程同时尝试写入db,一个线程将在另一个线程之前到达更新操作,第二个线程应该等待10秒,然后抛出。 但相反,线程挂起,直到另一个线程完成,无论设置的超时如何。 看看这个例子: 我预期在第二个请求中,事务将等待超时设置,然后抛出,但它将永远死锁。 Hibernate通过以下方式生成我对数据库的请求: 在这个答案中,我看到<

  • 问题内容: 从技术角度来看,这两个列表之间有什么区别?首先是lock的 java doc中提供的一个。其次是我的。 1。 2。 问题答案: 原因可以在以下文档的javadoc中找到: 实施注意事项 锁实现通常会限制哪些线程可以释放锁(通常只有锁的持有者才能释放该锁), 并且如果违反该限制,则可能引发(未经检查的)异常 。任何限制和异常类型都必须由那个Lock实现记录下来。 同样,a 可能会因未检查

  • 问题内容: 在MySQL数据库中存储IP地址的最佳字段类型和长度是什么? IPv6呢? 问题答案: 将IP存储为,然后使用和功能存储/检索IP地址。 样例代码:

  • 问题内容: 我上了一堂课,想跟踪学生的统计数据。我打算稍后制作一个GUI来处理这些数据。 我的主要问题是:保存和以后检索此数据的最佳方法是什么? 我已经读过关于pickle和JSON的文章,但是我并没有真正了解它们的工作方式(尤其是关于它们如何保存数据的信息,例如哪种格式和位置)。 问题答案: 对于持久性数据(存储有关学生的信息),数据库是一个不错的选择。如前所述,Python附带了Sqlite3

  • 我没有成功地将Spring数据发送给postgres a以进行NoWait更新。 我已经在存储库中尝试过了: 配置(代码段) 我甚至将EntityManager注入到服务中,结果返回0: info(em.getproperties().get(“javax.persistence.lock.timeout”)); 但是上面只给了我“用于更新”,没有设置NOWAIT部分。我设置的事情是正确的(从另一

  • 在使用Spring Boot应用程序时,我们根据不同的环境使用不同的文件。 我担心如果有人获得我们的应用程序属性并获得所有重要细节会发生什么。 有没有什么好的方法可以把重要的凭证放在某个地方,并在我们基于环境的Spring Boot应用程序中获得它们?