gpt4 book ai didi

postgresql - c3p0: session 级咨询锁

转载 作者:行者123 更新时间:2023-11-29 12:31:25 25 4
gpt4 key购买 nike

我正在使用 c3p0 和 postgres。我有一个多线程应用程序,如果没有适当的锁定,不同的线程可能会意外地更新同一条记录。为了防止这种情况,我打算使用咨询锁。

SELECT pg_advisory_lock(id) FROM ...;

但是,我不确定我是否真的可以将咨询锁与连接池结合使用,因为如果用于创建锁的连接关闭了怎么办(这对应用程序逻辑是透明的)?相应的锁是否被释放?

最佳答案

是的,连接关闭时会释放锁(建议锁和其他锁)。

不过,如果连接返回到池中,它们可能不一定被释放;事务级锁是因为池程序将ROLLBACK 任何打开的事务,但咨询锁只有在您的连接池程序知道 run the PostgreSQL-specific DISCARD ALL; statement 时才会被释放。在将 session 返回到连接池之后。

In order to prevent this, I intend to use advisory locks.

为什么?您正在阻止对记录 的更新,因此您有一个可以很好地锁定的普通行。你的过程应该是:

  1. 从连接池中检查一个连接
  2. SELECT * FROM the_table WHERE id = 123 FOR UPDATE
  3. 完成应用程序中要求的工作
  4. UPDATE the_table SET whatever = blah WHERE id = 123
  5. 将连接归还给连接池

这要求您在相同的连接 上为这三个步骤持有一个打开的事务。如果您的体系结构阻止您这样做并在 (2) 之后将连接返回到池,那么它可能也会阻止使用建议锁定,因为您需要持有相同的底层连接来管理建议锁定。

如果是这种情况,您必须使用 optimistic concurrency control (通常称为“乐观锁定”),一种为无状态 Web 应用程序创建的设计。您在实体中存储一个版本字段,您的流程类似于:

  1. SELECT col1, col2, entity_version FROM the_table WHERE id = 123(假设 entity_version 返回值 42)
  2. 完成应用中要求的工作
  3. UPDATE the_table SET whatever = blah, entity_version = 43 WHERE id = 123 AND entity_version = 42

如果 entity_version 已被另一个 session 更改,则 UPDATE 上的 WHERE 子句将不匹配,更新将影响零行.您测试受影响的行数并重试整个操作或在发生这种情况时根据需要向用户报告错误。

许多 ORM 已经实现了乐观并发控制,例如 Hibernate 和其他 JPA ORM。您不必将它与 ORM 一起使用,这只是最常见的用途,因为 ORM 鼓励“选择然后更新”反模式,否则 SQL DB 应该避免这种模式。

关于postgresql - c3p0: session 级咨询锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17827594/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com