Эта статья является зеркальной статьёй машинного перевода, пожалуйста, нажмите здесь, чтобы перейти к оригиналу.

Вид: 24272|Ответ: 0

[Источник] EF Core pit: DbContextPool вызывает исчерпание соединений пула соединений базы данных

[Скопировать ссылку]
Опубликовано 2019-11-18 14:41:59 | | |
DbContextPool — это новая функция, введённая в ASP.NET Core 2.1, которая экономит накладные расходы на создание экземпляра DbContext, но в ней скрыта небольшая яма.
Недавно проект ASP.NET Core работал непрерывно в течение определённого времени, после чего в журналах появилась ошибка, что пул соединений базы данных достиг максимального количества соединений:


System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
   at System.Data.Common.ADP.ExceptionWithStackTrace(Exception e)
Сначала я подумал, что это какой-то код, из-за которого DbContext удаляется правильно, но в коде не нашёл никаких подсказок. Позже сомневаться не в чем было — только DbContextPool, поэтому я попытался удалить DbContextPool, но ошибка исчезла. Это действительно было вызвано DbContextPool, но что заставляет людей задуматься, так это то, что DbContextPool изначально задумывался для экономии расходов на создание экземпляров DbContext, так как он может потреблять больше соединений к базе данных, а нагрузка этого проекта очень низкая, как он может потреблять весь пул соединений?
Сегодня я говорил об этой странной проблеме на еженедельном собрании, и вдруг подумал, что каждый экземпляр DbContext будет занимать соединение с базой данных (SqlConnection), и когда DbContextPool не включён, как только запрос завершится, соответствующий экземпляр DbContext будет уничтожен, а соединение с базой данных возвращается в пул соединений. При использовании DbContextPool DbContext не утилизируется, а после завершения запроса возвращается в DbContextPool, а DbContext возвращается в отдельный пул, что означает, что соответствующее соединение с базой данных не возвращается в пул соединений, к которому он принадлежит. Каждый DbContext в DbContextPool соответствует соединению с базой данных, и для каждого дополнительного DbContext в DbContextPool в пуле соединений базы данных будет на одно соединение с базой данных. Когда два пула разного размера, а DbContextPool больше пула соединений базы данных, возникает проблема: DbContextPool свободно заполняет DbContext в пул в зависимости от размера собственного пула (допустим, он 128), игнорируя размер пула соединений базы данных (если он 100), и вышеописанная ошибка возникает, когда заполнён 101-й DbContext.
В этом проекте используются настройки по умолчанию, вызывает ли она такую проблему?

Смотря на исходный код реализации DbContextPool, ограничение по умолчанию для пула обнаружения составляет 128


Если посмотреть исходный код реализации SqlConnention, можно увидеть, что по умолчанию лимит размера для пулов соединений — 100

Стандартная настройка вызовет проблему, а это на самом деле небольшая ошибка.

Зная причину, решение простое — установить poolSize DbContextPool меньше Max_Pool_Size пула соединений базы данных





Счёт

Количество участников1МБ+1 способствовать+1 Коллапс причина
Zmoli775 + 1 + 1 Наступай на яму и наступай на неё +1

Смотреть все рейтинги





Предыдущий:C# наследует определение IsAssignableFrom, IsSubclassOf
Следующий:Обходной путь основного исключения MySQL Entity Framework
Отказ:
Всё программное обеспечение, программные материалы или статьи, публикуемые Code Farmer Network, предназначены исключительно для учебных и исследовательских целей; Вышеуказанный контент не должен использоваться в коммерческих или незаконных целях, иначе пользователи несут все последствия. Информация на этом сайте взята из Интернета, и споры по авторским правам не имеют отношения к этому сайту. Вы должны полностью удалить вышеуказанный контент с компьютера в течение 24 часов после загрузки. Если вам нравится программа, пожалуйста, поддержите подлинное программное обеспечение, купите регистрацию и получите лучшие подлинные услуги. Если есть нарушение, пожалуйста, свяжитесь с нами по электронной почте.

Mail To:help@itsvse.com