Я начал с этого - SemaphoreSlim для защиты пула соединений от истощения и быстро понял, что моя проблема в том, что соединения не возвращаются в пул, когда я удаляю DbContext.
Учтите, что все подключения к базе данных выполняются внутри оператора using, как такового:
using (var context = ContextFactory.GetContext<PostgreSqlDatabaseContext>(connectionString))
{
var query = $"SELECT * FROM public.\"MyTable\" WHERE \"MyId\" = '{id}'";
var result = await context.MyTable.FromSql(query).SingleOrDefaultAsync();
return result;
}
ContextFactory выглядит так:
internal class ContextFactory
{
public static T GetContext<T>(string sqlConnection) where T : DbContext
{
var optionsBuilder = new DbContextOptionsBuilder<PostgreSqlDatabaseContext>();
optionsBuilder.UseNpgsql(sqlConnection);
return new PostgreSqlDatabaseContext(optionsBuilder.Options) as T;
}
}
Независимо от того, что я делаю со строкой подключения, устанавливая Enlist=true в соответствии с предложением здесь или регулируя соединения с использованием SemaphoreSlim в соответствии с предложением здесь, я получаю тот же результат:
The connection pool has been exhausted, either raise MaxPoolSize (currently 20) or Timeout (currently 15 seconds)
Npgsql вообще работает? Что здесь происходит?
Обратите внимание, что я прочитал это и это, и они не совпадают.
Кстати, имена классов и сущностей очень подозрительны. Предполагается, что контексты обрабатывают сущности. Они не являются соединениями, но PostgreSqlDatabaseContext предлагает использовать их как соединения. Вы пытаетесь выполнить необработанный запрос к набору сущностей Браузер (в единственном числе?), Но ищете другую таблицу по идентификатору. Если вы хотите загрузить браузер из набора Браузеры, вы можете написать context.Browsers.FindAsync(someID) для первичного ключа или context.Browsers.SingleOrDefaultAsync(b=>b.MyID==id).
'; Drop table Users;-- в качестве значения идентификатора?
@PanagiotisKanavos - в ответ на «возвращается в пул при удалении контекста» контекст удаляется при закрытии оператора using. Какие потенциальные части этого примера вы видите, удерживая связи открытыми? И да - контексты должны обрабатывать entities, как мы пытались сделать изначально. Этот пример - результат разочарования из-за ошибки. Естественно, мы пробовали использовать EF, как он будет использоваться с MSSQL, но он просто не работает. Какой «меньший» пример я могу предоставить? : /
Один без какого-либо пользовательского кода ваш. Даже с SQL Server этот статический фабричный метод будет странный. Почему бы не указать подключение в конфигурация контекста? Одно соединение, заключенное в using, которое запускает одну команду, покажет исчерпание пула, если оно существует. Если вы повторите это внутри цикла 100 раз и не получите исчерпания пула, вы узнаете, что нет ошибки истощения.
Как насчет предоставления простого, полного и минимального образца кода, воспроизводящего проблему? Таким образом мы сможем точно понять, что вы делаете.
Я бы сказал, что соединения не могут быть возвращены в пул, потому что они заняты выборкой данных. Вы можете включить журналы, чтобы узнать больше.
@Marcus Я получаю то же самое _ я считаю, что USING неправильно закрывает соединения для Npgsql. На github есть вид болтовни вокруг этого. Но нет решения





Соединения находятся возвращаются в пул при удалении контекста, если вы не открываете их отдельно и не оставляете открытыми. Создайте пример минимальный, который воспроизводит поведение без каких-либо фабрик, специального кода или даже необработанных SQL-запросов. Если вы хотите протестировать сам Npgsql, используйте простые классы ADO.NET, а не EF. Я подозреваю, что в обоих случаях вы обнаружите, что утечек нет. Если это произойдет, вы будете знать, что это остальной код кода, который держит вещи открытыми, когда этого не следует