首页 > 解决方案 > PostgreSQL 咨询锁在事务中不起作用吗?

问题描述

我正在使用带有 Npgsql 驱动程序的 C# 连接到 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: tuple concurrently updated”。如果我使用LOCK TABLE而不是咨询锁,它可以工作。如果我在没有交易的情况下这样做,它也可以。但是,每次我想锁定时删除事务似乎是一个脆弱的设计。

注意:我已经用 Npgsql Transactions API 和BEGIN/尝试过,COMMIT结果相同。

我认为锁作为互斥锁正常工作,那么事务出了什么问题?

标签: postgresqllockingconcurrencynpgsql

解决方案


推荐阅读