【问题标题】:Would this mutex implementation make sense in PostgreSQL?这种互斥锁实现在 PostgreSQL 中有意义吗?
【发布时间】:2019-08-11 12:32:36
【问题描述】:

我需要在 PostgreSQL 中实现数据库会话之间的同步。

在 SQL Server 中,我将通过创建自己的“锁定”表来实现它。

Create table MyLock(LockName VARCHAR(100) NOT NULL UNIQUE, LockOwner INT NULL)

我不使用显式事务来避免真正锁定事情,我会通过将我的会话 ID 设置为“所有者”来获取我的“单例”锁。

UPDATE MyLock
  SET LockOwner = *MySessionId*
  WHERE LockName = 'Singleton' 
  AND LockOwner IS NULL;

通过不使用显式事务,我不会阻止其他进程。 您可以将其视为“软锁”...

如果我的更新成功,那么我知道我“拥有”了锁,我可以处理一些代码,而其他人会等待。 如果我的更新没有更新,我知道其他人有“锁定”,我等待或放弃。

我需要在 PostgreSQL 中实现类似的东西。

你会这样做吗?

【问题讨论】:

    标签: postgresql synchronization mutex


    【解决方案1】:

    不,我会做不同的。

    问题是您需要不断轮询锁,这意味着不必要地浪费 CPU 时间或比必要的等待时间更长。

    这个要求非常适合 PostgreSQL 的advisory locks:

    您选择一个锁号,而不是像Singleton 这样的锁名称,例如1234.

    要获得锁,运行

    SELECT pg_advisory_lock(1234);
    

    要释放锁,运行

    SELECT pg_advisory_unlock(1234);
    

    这就像普通的数据库锁一样,如果锁不可用则暂停调用进程,并在锁持有者释放锁后立即恢复它。还有一些功能可以在不阻塞的情况下“轮询”咨询锁的可用性。

    这些锁独立于 PostgreSQL 的事务,它们一直保持到释放或数据库会话结束(因此不存在“孤立锁”的危险)。

    这些锁也不会干扰 autovacuum 操作。

    如果应用程序想要使用数据库技术进行同步,这是一个完美的工具。

    【讨论】:

    • 如果“客户端”软件执行某种连接池,如果我们不显式释放会话咨询锁,我们是否存在无意中传递会话咨询锁的潜在风险?
    • 是的,它们与会话相关联。
    • 在这种情况下如何处理客户端崩溃?就我而言,我有一个 JDBC 连接池,当客户端崩溃时,连接只是返回到池中,因此不会关闭会话,也不会释放锁。
    • 连接池通常在每个连接返回池时发送一个“清理”语句。使用它。
    • 我猜这取决于您使用的应用程序服务器,它不是 JDBC 的一部分。我也不知道详情。
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2019-09-26
    • 2011-07-20
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    相关资源
    最近更新 更多