c# - 多个 Npsql 连接
问题描述
我正在尝试创建一个简单的服务器(.Net Core 5.0),它通过 Npgsql + Npgsql.EntityFramework 与 PostgreSQL DB(v 13.1)进行通信。
我有创建新用户、授予某些权限并检索 OID 的代码:
string connString =
String.Format(
"Server={0};Username={1};Database={2};Port={3};Password={4};SSLMode=Prefer",
PSqlHost, User, DBname, PSqlPort, Password);
NpgsqlConnection psqlConnection = null;
try
{
using (psqlConnection = new NpgsqlConnection(connString))
{
psqlConnection.Open();
StringBuilder cmdBuilder = new StringBuilder();
cmdBuilder.Append(string.Format("CREATE USER {0} WITH LOGIN PASSWORD '{1}';\r\n", signIn.Login, signIn.Pass));
cmdBuilder.Append(string.Format("GRANT SELECT ON ALL TABLES IN SCHEMA public TO {0};\r\n", signIn.Login));
cmdBuilder.Append(string.Format("GRANT SELECT, UPDATE ON ALL TABLES IN SCHEMA users TO {0};\r\n", signIn.Login));
cmdBuilder.Append(string.Format("SELECT oid FROM pg_catalog.pg_authid WHERE rolname='{0}';\r\n", signIn.Login));
using (var pgCmd = psqlConnection.CreateCommand())
{
pgCmd.CommandText = cmdBuilder.ToString();
if (!pgCmd.IsPrepared) pgCmd.Prepare();
using (var reader = pgCmd.ExecuteReader())
{
if (!reader.HasRows) return TcpMessageSpec.Fail;
if (!reader.IsOnRow) reader.Read();
var oid = (uint)reader.GetValue(0);
}
}
}
return TcpMessageSpec.OK;
}
catch (PostgresException ex)
{
Log.Exception(ex.MessageText);
if (ex.SqlState == PostgresErrorCodes.InvalidPassword) return TcpMessageSpec.AuthFailed;
else if (ex.SqlState == PostgresErrorCodes.DuplicateObject) return TcpMessageSpec.UserExists;
return TcpMessageSpec.ConnectionFailed;
}
catch (Exception ex)
{
Log.Exception(ex.InnerException);
return TcpMessageSpec.ConnectionFailed;
}
finally
{
}
这段代码在单个线程中完美运行,但我希望它在多个线程中运行。
当我从五个或更多线程运行此代码时,我会捕获PostgresException: "XX000: tuple concurrently updated"
. 但是,一些线程成功了(没有例外,OID 被检索)。
尝试解决(但结果相同):
- 我尝试过 NPSql 的异步版本
- 使用 NpgsqlConnection 事务
- 批处理/非批处理命令查询
- 我读过类似的问题
但是我仍然不明白我的错误在哪里。
解决方案
tuple concurrently updated
是一个错误 PostgreSQL 有时会在某些 DDL 操作同时执行时返回(参见例如这个讨论)。这与 Npgsql 没有任何关系——您可能必须使用同步来确保这些 DDL 操作不会并行发生。
推荐阅读
- linux-kernel - 如何查找 dma_request_chan() 失败原因详情?
- python - 将多个字典与相同的模式组合
- ios - 类方法要求 'AFDataResponse
' 符合 Encodable & Encodable - node.js - 我们可以在哪里安全地存储 JWT 令牌?
- javascript - 引导模式不显示文本
- javascript - window.print() 后退出
- google-api - 谷歌日历关注事件更新
- spring-mvc - url Spring Pageable中的排序方向
- microsoft-dynamics - Microsoft Dynamics AX 2012 中的 KB 修补程序安装错误
- javascript - Vue中如何访问所有组件中对象内部的数据