我正在使用pg_try_advisory_lock遇到一些意外的(对我而言)行为。我相信这可能是连接池/超时相关。
pg_advisory_lock正在按预期工作。当我调用该函数并且所需的锁已被使用时,我的应用程序将等待,直到函数调用上的指定命令超时。
但是,当我用pg_try_advisory_lock替换并检查此函数的结果(true / false)以确定是否获取了锁时,某些场景允许多个进程(部署到ECS的单线程.net核心)获取“true”同一个锁定键。
在C#代码中,我已在IDisposable中实现并调用我的调用来释放锁并处置基础连接。这是我对pg_advisory_lock和pg_try_advisory_lock的调用的情况。所有需要同步的工作都发生在using块中。
我的操作理论是连接池/超时周围的设置在这里发挥作用。因为try调用没有阻塞,所以锁定的会话上下文“置于”postgres - 可能是因为连接空闲(?)。
如果这是原因,最简单的解决方案似乎是禁用try lock中使用的连接的任何类型的池。但由于现在汇集只是一种理论,因此开始针对特定解决方案似乎有点早。
任何想法可能是什么原因?
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)
事实证明这有点愚蠢。无需更改池。
我正在使用Dapper和NpgSql库。除非明确打开连接,否则在用于.Query()之后,NpgsqlConnection将返回到关闭状态。
这会影响我尝试/阻止咨询锁定调用版本的调用,尽管阻塞容量的方式不那么恶劣。