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<TContext>(
[NotNull] this IServiceCollection serviceCollection,
[NotNull] Action<DbContextOptionsBuilder> optionsAction,
int poolSize = 128)
where TContext : DbContext
=> AddDbContextPool<TContext, TContext>(serviceCollection, optionsAction, poolSize);

查看 SqlConnention 的 实现源码 发现连接池的默认大小限制是 100

internal const int Max_Pool_Size = 100;

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

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

services.AddDbContextPool<JobDb>(option =>
option.UseSqlServer(Configuration.DbConnectionStr()),
poolSize: 64);

EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽的更多相关文章

  1. Java使用数据库连接池连接Oracle数据库

    第一步:导入tomcat\lib 下的一个tomcat-dbcp.jar包第二步:在web\META-INF下新建一个context.xml文件,文件内容如下: <?xml version=&q ...

  2. 解决数据库连接池连接mysql时,每隔8小时mysql自动断开所有连接的问题

    解决数据库连接池连接mysql时,每隔8小时mysql自动断开所有连接的问题 最近有个问题非常讨厌,我们的工程中使用自己的连接池连接mysql数据库,可mysql数据库每隔8小时就会自动断开所有链接, ...

  3. net core 小坑杂记之配置文件读取(不定期更新)

    其实很早就想写了,原想等积累差不多了再写的,但是发现遇到一个当时记下效果会比较好,所以就不定期更新这个系列了,后面获取会整个整理一下. 此篇记载net core入门时踩的一些坑,网上教程太少了,也不规 ...

  4. .net Core 调用EF Core 爬坑

    .net Core 中调用 EF Core项目 首先得建一个类库供.net Core 的主项目引用:其次,在.net Core 中做注入:最后,在页面中调用 1.类库项目中的操作 1.新建类库项目 2 ...

  5. Myeclipse WEB工程JSP使用JNDI 数据库连接池连接Mysql数据库

    在网上查了很多,最后实现了.下面写一下过程: 首先,在WEBROOT/META-INF下建一个文件context.xml,内容为: <?xml version="1.0" e ...

  6. springboot druid 数据库连接池连接失败后一直重连

    在使用个人阿里云测试机,在查询实时输出日志时,看到数据库连接失败后,服务器一直在重连服务器.开始以为是遭受重复攻击,后面把服务重启后,就没有出现一直重连的情况.看以下输出日志: 2022-02-09 ...

  7. net core 小坑杂记之配置文件读取 02 (控制器里读)

    上次更新博客的时候提到了如何在EF的上下文里读取配置,这次介绍一下在控制器里如何读取. 先说一种简单易懂的: 首先以键值对的形式在appsettings里添加一条配置信息,接着Startup里注入配置 ...

  8. 使用 EF Core 的 EnableRetryOnFailure 解决短暂的数据库连接失败问题

    阿里云服务器有时会出现短暂的连接不上数据库服务器(RDS)的问题,之前由于没有启用 Entity Framework Core 的失败重试功能(默认是禁用的),短暂的连接失败立马会引发下面的异常从而出 ...

  9. EF Core 小技巧:迁移已经应用到数据库,如何进行迁移回退操作?

    场景描述:项目中存在两个迁移 Teacher 和 TeachingPlan ,TeachingPlan 在 Teacher 之后创建,并且已经执行 dotnet ef database update ...

随机推荐

  1. python数据结构之堆(heap)

    本篇学习内容为堆的性质.python实现插入与删除操作.堆复杂度表.python内置方法生成堆. 区分堆(heap)与栈(stack):堆与二叉树有关,像一堆金字塔型泥沙:而栈像一个直立垃圾桶,一列下 ...

  2. [Linux容器]当我们谈容器的时候,我们在谈什么

    Docker在当下很火,那么,当我们谈Docker,谈容器的时候,我们在谈什么? 或者说,你对Docker,对容器了解吗?容器,到底是怎么一回事儿? 这篇文章着重来讲一下Linux容器,为什么强调Li ...

  3. 027_git添加多账号设置

    一. 注意事项: (1)公钥文件权限设置问题 现象: Permissions 0644 for '/Users/arunyang/.ssh/id_rsa_ele_me.pub' are too ope ...

  4. OpenCV3编程入门-读书笔记1

    一.OpenCV概述 1.OpenCV全程Open Source Computer Vision Library,即开源计算机视觉库.它是一个跨平台的开源计算机视觉库,可以运行在windows.lin ...

  5. 【原创】大叔问题定位分享(9)oozie提交spark任务报 java.lang.NoClassDefFoundError: org/apache/kafka/clients/producer/KafkaProducer

    oozie中支持很多的action类型,比如spark.hive,对应的标签为: <spark xmlns="uri:oozie:spark-action:0.1"> ...

  6. 【原创】大数据基础之Kudu(2)移除dead tsever

    当kudu有tserver下线或者迁移或者修改hostname之后,旧的tserver会一直以dead状态出现,并且tserver日志中会有大量的连接重试日志,一天的错误日志会有几个G, W0322 ...

  7. PADS Logic VX.2.3 修改软件界面语言

    操作系统:Windows 10 x64 工具1:PADS Logic VX.2.3 2019.03.19 星期二 晴 记录一件伤心的事,因为公司要求统一原理图设计.PCB Layout工具,所以,以后 ...

  8. jfinal undertow web.xml

    由于 undertow 是为嵌入式 server 而生,所以 jfinal undertow 项目是不需要 web.xml 这个文件的 线上这版 Filter.Servelt.Listener.Web ...

  9. #Node.js的fs导入遇到的问题和解决方案

    一直在使用VS Code,今天打算用Node.js进行文件IO时候遇到了一些问题,fs是Node.js的核心功能之一,一开始我用Javascript编写fs模块的导入. var fs = requir ...

  10. 百度上传插件---webuploader的使用

    需求:朋友让找一个兼容IE8的上传插件,卧槽,IE8,我当时是崩溃的,然后就搜到了这个百度的插件,官网是这样描述的 WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HT ...