Консультативные блокировки PostgreSQL не работают в транзакциях? - PullRequest
0 голосов
/ 19 сентября 2018

Я использую C # с драйвером Npgsql для подключения к postgresql 9.6.9.У меня есть два сервера, которые подключаются к одной и той же базе данных и выполняют следующий код инициализации в цикле, чтобы убедиться, что они конфликтуют друг с другом:

using (var txScope = new TransactionScope())
using (var connection = Connection())
{
    connection.EnlistTransaction(Transaction.Current);
    using (var cmd = new NpgsqlCommand("SELECT pg_advisory_lock(1024)", connection))
    using (cmd.ExecuteReader()) { }

    // The following line fails:
    using (var cmd = new NpgsqlCommand(@"CREATE OR REPLACE FUNCTION update_column()   
        RETURNS TRIGGER AS $$ BEGIN RETURN NEW; END; $$ language 'plpgsql'; ", connection))
    {
        cmd.ExecuteNonQuery();
    }

    using (var cmd = new NpgsqlCommand("SELECT pg_advisory_unlock(1024)", connection))
    using (cmd.ExecuteReader()) { }

    txScope.Complete();
}

Консультативная блокировка должна помешать выполнению запроса CREATE большечем один раз в настоящее время, но он последовательно терпит неудачу с «Npgsql.PostgresException (0x80004005): XX000: одновременно обновляется кортеж», где создается функция.Если я использую LOCK TABLE вместо консультативной блокировки, это работает.Если я делаю это без транзакций, это также работает.Тем не менее, кажется, что хрупкий дизайн для удаления транзакций каждый раз, когда я хочу заблокировать.

Примечание: я пробовал это с API транзакций Npgsql и с BEGIN / COMMIT с тем же результатом.

Я думаю, что блокировка правильно работает как мьютекс, так что же не так с транзакцией?

...