欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

net core mysql 连接池_EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽

发布时间:2023/11/27 62 豆豆
生活随笔 收集整理的这篇文章主要介绍了 net core mysql 连接池_EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽

发布时间:2019-02-18 22:05,

浏览次数:1152

, 标签:

EF

Core

DbContextPool

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 不能正常 Dispose ,但在代码中没有找到任何相关线索。后来实在没有其他可以怀疑的地方,唯有

DbContextPool ,于是尝试去掉 DbContextPool ,结果错误就消失了。果然是 DbContextPool 引起的,但让人纳闷的是

DbContextPool 本来就是为了节省创建 DbContext

实例的开销,怎么反而消耗更多数据库连接,而且这个项目的负载很低,怎么可能把整个连接池都消耗殆尽呢?

今天在周会上谈了这个怪问题,后来突然想到:每个 DbContext 实例都会占用一个数据库连接(SqlConnection),不启用

DbContextPool 的时候,请求一结束,对应 DbContext 实例就被 Dispose ,数据库连接就会被放回连接池。而使用

DbContextPool 的时候,请求结束后 DbContext 不会被 Dispose 而是被放回 DbContextPool ,DbContext

被放回属于自己的池中,就意味它对应的数据库连接不会被放回它所属的连接池。DbContextPool 中的每一个 DbContext

都对应一个数据库连接,DbContextPool 中每多一个 DbContext ,数据库连接池中就会少一个数据库连接。当这两个池的大小不一样且

DbContextPool 大于数据库连接池,问题就来了,DbContextPool 根据自家池(假设是128)子的大小畅快地向池中填 DbContext

,浑然不顾数据库连接池的大小(假设是100),当填到第 101 个 DbContext 时就会出现上面的错误。

这个项目中用的都是默认设置,是不是默认设置就会触发这个问题呢?

查看 DbContextPool 的 实现源码

发现池的默认大小限制是 128

public static IServiceCollection AddDbContextPool( [NotNull] this

IServiceCollection serviceCollection, [NotNull] Action

optionsAction, int poolSize = 128) where TContext : DbContext =>

AddDbContextPool(serviceCollection, optionsAction,

poolSize);

查看 SqlConnention 的 实现源码

发现连接池的默认大小限制是 100

internal const int Max_Pool_Size = 100;

默认设置就会触发问题,实实在在的一个小坑。

知道了原因,解决起来就很简单了,将 DbContextPool 的 poolSize 设置为小于数据库连接池的 Max_Pool_Size

services.AddDbContextPool(option =>

option.UseSqlServer(Configuration.DbConnectionStr()), poolSize: 64);

总结

以上是生活随笔为你收集整理的net core mysql 连接池_EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。