Как использовать «Попробовать» Postgres Advisory Locks - PullRequest
0 голосов
/ 22 апреля 2019

Я испытываю неожиданное (для меня) поведение при использовании pg_try_advisory_lock.Я полагаю, что это может быть связано с пулом соединений / тайм-аутом.

pg_advisory_lock работает как положено.Когда я вызываю функцию, и требуемая блокировка уже используется, мое приложение ожидает до истечения заданного времени ожидания команды при вызове функции.

Однако, когда я заменяю на pg_try_advisory_lock и вместо этого проверяю результат этой функции (true/ false) чтобы определить, была ли получена блокировка, какой-то сценарий позволяет нескольким процессам (однопоточное ядро ​​.net, развернутое в ECS) получать «true» на одном и том же ключе блокировки одновременно.

в коде C #Я реализовал в IDisposable и сделал мой вызов, чтобы снять блокировку и избавиться от базового соединения при утилизации.Это касается как моих вызовов pg_advisory_lock, так и pg_try_advisory_lock.вся работа, которая должна быть синхронизирована, происходит внутри блока использования.

Моя теория работы заключается в том, что здесь действуют настройки пулов / тайм-аутов соединений.поскольку вызов try не блокируется, контекст сеанса для блокировки «удаляется» на postgres - возможно, в результате простоя соединения (?).

если это является причиной, простейшее решение кажетсябыть, чтобы отключить любой вид пулов для соединений, используемых при попытке блокировки.но поскольку объединение - это всего лишь теория на данный момент, кажется, рано начинать нацеливаться на конкретное решение.

есть идеи, что может быть причиной?

Пример 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 голосов
/ 23 апреля 2019

Это оказалось довольно глупо. Никаких изменений в пуле, где это необходимо.

Я использую библиотеки Dapper и NpgSql. NpgsqlConnection возвращается в закрытое состояние после использования в .Query (), если соединение явно не открыто.

Это повлияло на оба моих звонка, чтобы попытаться / заблокировать версии вызовов консультативной блокировки, хотя и в меньшей степени в плане блокировки.

...