在以下情况下需要一些澄清。 kubectl delete deployment -n metallb-system controller
kubectl delete daemonset -n metallb-system speaker
和CanAddConcurrently
失败。
DoesNotTimeout
-(Npgsql.PostgresException:55000:已准备好的事务被禁用)。我了解这是因为我在postgres配置中禁用了此功能,但是为什么这会升级为准备好的事务?是因为它实际上得到了另一个NpgsqlConnection吗?如果是这样,这真的需要进行分布式交易吗?我可以使用knex运行相同的示例,使用具有相同池限制的node-postgres,在postgres中禁用准备好的事务,而在node.js下不会出现问题
CanAddConcurrently
-(连接池已耗尽)我不明白为什么此处未重用池化连接。是否因为与测试中的顶级TransactionScope相关联而将其丢弃?即使在这种情况下,如果连接与同一事务相关联,为什么也不能重用该连接。我可以使用knex,具有相同池限制的node-postgres运行相同的测试用例,而在node.js下没有问题。
DoesNotTimeout
using Npgsql;
using System.Threading.Tasks;
using System.Transactions;
namespace TestCases
{
public class Service
{
private readonly string connectionString;
public Service(string connectionString)
{
this.connectionString = connectionString;
}
// I am aware this is only executing 1 query so does not have a need for an embedded transaction, this is just to keep example simple
// removing the TransactionScope does not fix the issue, but for closer sample to original code it is here
public async Task Add(string val)
{
using (var nestedScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
using (var conn = new NpgsqlConnection(this.connectionString))
{
await conn.OpenAsync();
var cmd = new NpgsqlCommand("INSERT INTO data(value) values(@p);", conn);
cmd.Parameters.AddWithValue("p", val);
await cmd.ExecuteNonQueryAsync();
nestedScope.Complete();
}
}
}
}
答案 0 :(得分:0)
您需要确切了解Task.WhenAll()
(以及可能是异步的)的运行方式。
您的上述代码在相同的事务范围内同时{em {em} 十次,然后等待这10次调用完成。每次调用都会打开一个新的池连接,并尝试使用程序中存在的单个事务作用域。当一个事务作用域(即分布式事务)征集了多个连接时,这就是升级发生的原因。
在第二个示例中,这可能也解释了池耗尽的问题-这与不重新使用池连接有关,而是与您尝试同时使用太多 有关
您应该使用标准的foreach串行运行代码,仅在上一个操作完成后才执行下一个操作。可以同时运行多个操作-为了获得更好的性能-但您绝对不能在它们之间共享相同的事务范围。