PostgreSQL咨询锁在事务内不起作用吗?

时间:2018-09-19 06:20:01

标签: postgresql locking concurrency npgsql

我正在使用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而不是咨询锁,它将起作用。如果我不做任何交易,它也会起作用。但是,每次我想锁定时删除事务似乎都是一种脆弱的设计。

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

我认为锁可以正确地用作互斥锁,那么事务出了什么问题?

0 个答案:

没有答案