我正在使用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
尝试了相同的结果。
我认为锁可以正确地用作互斥锁,那么事务出了什么问题?