You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

基于.NET 4.6.1的C#控制台应用遇Oracle数据访问打开失败错误

解决Oracle EF Provider "The underlying provider failed on Open" 74次运行后报错的问题

看起来你遇到的是典型的数据库连接池耗尽问题——前74次运行正常,之后突然打不开连接,大概率是因为数据库连接没有被正确释放,慢慢占满了连接池,第75次请求拿不到可用连接就触发报错了。结合你的场景和代码,我给你几个针对性的排查和解决步骤:

1. 管好DbContext的生命周期(最核心的解决办法)

你代码里用到的thingEntity这个DbContext实例,是不是每次查询都复用同一个?或者用完之后没有正确释放?控制台应用里如果长时间持有DbContext,它会一直占用数据库连接,不会放回连接池,次数多了自然就把池占满了。

正确的做法是每次操作都用using语句包裹DbContext,确保用完就释放:

using (var thingEntity = new YourDbContextType()) // 替换成你的DbContext实际类型
{
    THING tempThing = thingEntity.THINGS
        .AsNoTracking()
        .Where(d => d.THING_ID == thi)
        .SingleOrDefault();
    // 这里处理查询到的tempThing
}

using语句会自动调用DbContext的Dispose()方法,把持有的数据库连接放回连接池,从根源上避免连接被一直占用的情况。

2. 调整Oracle连接池配置(辅助优化)

如果确认连接释放没问题,但还是偶尔出现这个问题,可以调整连接字符串里的连接池参数,比如增大最大连接数,或者设置连接的生命周期:

Data Source=你的Oracle数据源;User Id=用户名;Password=密码;Max Pool Size=200;Connection Lifetime=120;Min Pool Size=5;
  • Max Pool Size:连接池允许的最大连接数,默认是100,你可以根据业务量适当调大,但这只是治标方案,核心还是要确保连接能正确回收。
  • Connection Lifetime:连接在池里的最长存活时间(秒),到期后会被自动销毁,避免持有无效的旧连接。

3. 验证连接池是否真的被耗尽

你可以用Oracle的系统视图查看当前的连接数,确认是不是连接被占满了:
执行以下SQL查询(用你的数据库用户登录):

SELECT COUNT(*) AS active_connections FROM v$session WHERE username = '你的数据库用户名';

运行你的程序,到第74次之后再查这个数值,如果接近连接池的最大数(默认100),那就能实锤是连接没释放导致的问题。

4. 关于AsNoTracking()的补充

你已经用了AsNoTracking(),这个是个好习惯——它告诉EF不要跟踪查询到的实体,能减少内存占用,也不会影响连接的释放,所以这个点没问题,不用调整。

最后提醒下:如果你的控制台应用是循环执行这个查询的长运行程序,一定要确保每次循环都新建并释放DbContext,绝对不能复用同一个DbContext实例,否则不仅会占连接,EF的缓存也会越来越大,导致其他问题。

内容的提问来源于stack exchange,提问作者Will T

火山引擎 最新活动