如何使用“尝试” Postgres咨询锁

时间:2019-04-22 12:32:50

标签: postgresql dapper npgsql locks

我正在使用pg_try_advisory_lock遇到一些意外(对我而言)的行为。我相信这可能与连接池/超时有关。

pg_advisory_lock运行正常。当我调用该函数并且所需的锁已在使用中时,我的应用程序将等待直到该函数调用上指定的命令超时。

但是,当我替换为pg_try_advisory_lock并检查此函数的结果(是/否)以确定是否已获取锁定时,某些情况下允许多个进程(将单线程.net核心部署到ECS)获取“ true”。 ”同时显示在同一锁定键上。

在C#代码中,我已在IDisposable内实现,并进行了调用以释放锁定并处置基础连接。我对pg_advisory_lock和pg_try_advisory_lock的调用都属于这种情况。所有需要同步的工作都发生在using块内。

我的操作理论是,围绕连接池/超时的设置在这里起作用。由于try调用不会阻塞,因此锁的会话上下文在postgres处“处理”-可能是由于连接为idle(?)导致的。

如果是原因,那么最简单的解决方案似乎是为尝试锁定中使用的连接禁用任何类型的池。但由于此时池化只是一个理论,因此开始针对特定解决方案似乎还为时过早。

任何想法可能是什么原因?

C#示例

using (Api.Instance.Locking.TryAcquire(someKey1, someKey2, out var acquired))
{
    if (acquired)
    {
        // do some locked work
    }
}

引擎盖下。 TryAcquire正在呼叫

select pg_try_advisory_lock as acquired from pg_try_advisory_lock(@key1,@key2)

1 个答案:

答案 0 :(得分:0)

这真是愚蠢。不需要更改池。

我正在使用Dapper和NpgSql库。除非显式打开连接,否则NpgsqlConnection在使用.Query()后将返回关闭状态。

这影响了我两个尝试/阻止顾问锁调用版本的调用,尽管对阻止能力的不利影响较小。