postgresql Postgres连接池不适用于. NET core 6事务范围

omqzjyyz  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(2)|浏览(222)

我正在使用Npgsql和Dapper从.NET 6应用程序连接到postgres db。我在postgres连接中启用了连接池。
请参阅https://www.npgsql.org/doc/connection-string-parameters.html
命令在事务范围内执行。我正在执行多个命令,每个命令都使用NpgsqlDataSource.OpenConnection方法打开新的连接。
调用transationscope.Complete时出错。以下是错误。
消息:System.TransactionAbortedException:事务已中止。---- Npgsql.PostgresException:55000:已准备的事务被禁用
我们理解这意味着连接不会被重用,因为它试图启动准备好的事务。这与www.example.com和www.example.com的最后一帕拉中的记录不符https://www.npgsql.org/doc/basic-usage.html#systemtransactions-and-distributed-transactionshttps://www.npgsql.org/doc/basic-usage.html#pooling
我们做错了什么
请帮帮我

edit 1附加代码示例

using (var transactionScope = new TransactionScope()) 
{
  
   using connection1 = NpgsqlConnection();
       
    await connection1.ExecuteAsync("procedure1"); 

    using connection2 = NpgsqlConnection();
    await connection2.ExecuteAsync("procedure2");
    
    transactionScope.Complete()
}


private static NpgsqlConnection NpgsqlConnection()
{
    string connectionString = "User ID=postgres;Password=*****;Host=hostName;Port=5432;Database=DBTestPostgres;Pooling=true;";
    NpgsqlDataSourceBuilder dataSourceBuilder = new NpgsqlDataSourceBuilder(connectionString); ,
    using NpgsqlDataSource dataSource = dataSourceBuilder.Build();
    NpgsqlConnection conn = dataSource.OpenConnection();
    return conn;
}

我期望相同的连接应该被重用,因为连接字符串中的池是打开的。

jvidinwx

jvidinwx1#

似乎您希望避免分布式事务(这是个好主意,因为它们有严重的开销,而且还需要服务器配置)。
文件规定:
请注意,如果您在环境事务中打开和关闭到同一数据库的连接,而没有同时打开两个连接,Npgsql将在内部重用相同的连接,从而避免了对分布式事务的需要
但你实际上有两个并发连接。您需要更改代码以关闭连接,使用旧样式的using块,而不是using语句。

using (var transactionScope = new TransactionScope()) 
{
    using (var connection1 = NpgsqlConnection())
    {
        await connection1.ExecuteAsync("procedure1");
    }

    using (var connection2 = NpgsqlConnection())
    {
        await connection2.ExecuteAsync("procedure2");
    }
    
    transactionScope.Complete()
}
utugiqy6

utugiqy62#

您可以使用此代码进行连接。确保在配置文件中用正确的连接字符串名称替换“DataBase”。

builder.Services.AddScoped<IDbConnection>(provider =>
{
    var connectionString = provider.GetRequiredService<IConfiguration>().GetConnectionString("DataBase");
    return new NpgsqlConnection(connectionString);
});

相关问题