8.6K Star 14.2K Fork 4.2K

GVPdotNET China/Furion

 / 详情

从1.15.*升级到1.18.5后,数据库连接池存在连接泄漏问题。

已完成
创建于  
2021-04-09 19:30

Furion 版本号

1.18.5


Web 项目类型

  • WebApi
  • Mvc
  • Razor Pages
  • Blazor Server

描述你的问题

从1.15.*升级到1.18.5后,数据库连接池存在连接泄漏问题。

项目是老项目迁移过来的,数据库是ms sqlserver2005,很多业务原来是存储过程实现,迁移使用ISqlDispatchProxy实现,例如:
[SqlProcedure("csp_GetSysVar")]
string GetSysVar(string SysName);

调用方是rabbitmq的消费者,获取服务方法,例如
_sql = (IxxSql)App.ServiceProvider.GetService(typeof(IxxSql));

数据库连接字符串
"DbConnection": "Server=127.0.0.1;Database=smart;User=sa;Password=xxx;Pooling=true;Min Pool Size=20;Max Pool Size=100;Connection Lifetime=180",

升级到最新版本1.18.5后,运行一段时间后,会报连接池耗尽的异常
select spid,login_time ,last_batch ,sql_handle
from sys.sysprocesses
发现连接池确实满了,很多连接创建后,不会被再次使用(last_batch 还是第一次调用后的时间)。
通过sql_handle 查询大部分都是调用存储过程。

项目回退到1.15.9后,运行正常。


异常堆栈信息


代码或代码仓库


数据库信息

  • Sqlite
  • SqlServer
  • Mysql
  • Oracle
  • PGSql
  • Firebird
  • Cosmos

期待结果


评论 (13)

蔡宙航 创建了任务 4年前
蔡宙航 关联仓库设置为dotNET China/Furion 4年前
蔡宙航 修改了描述 4年前
展开全部操作日志

有没有详细的异常堆栈

蔡宙航-caizhouhangcc 蔡宙航
回复 百小僧 拥有者
4年前

泄漏本身没有异常堆栈,出错的时候,是连接池满的异常

蔡宙航 修改了描述 4年前

输入图片说明
比较了一下1.15和1.18版本的DbContextPool.cs的代码,这个clear导致的?

我刚刚回到家,我晚上我来测试一下,我有工具可以测试的

同样的昨天我也遇到连接池满的问题,

引发了异常: System.Private.CoreLib.dll 中的“System.ObjectDisposedException”(“Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.”) System.ObjectDisposedException

经调试,问题出在 SaveAuditEntitys方法的 _auditEntityRepository.InsertNowAsync(auditEntitys);部分,改成
_auditEntityRepository.InsertAsync(auditEntitys);后没有ObjectDisposedException异常,并且数据库连接也正常关闭

1.18可以复现出来
用的EasyNetQ客户端
消息体
[Queue("DbContextTest", ExchangeName = "DbContextTest")]
public class DbContextTestMessage
{
public string Data { get; set; }
}
消费者
public class DbContextTestMessageConsumer : IConsumeAsync
{
[AutoSubscriberConsumer(SubscriptionId = "Test")]
public async Task ConsumeAsync(DbContextTestMessage message, CancellationToken cancellationToken = default)
{
var xxx = App.ServiceProvider.GetService().xxx; //这里调用存储过程

        await Task.Delay(1000);

        xxx.LogError("DbContextTestMessageConsumer");
    }
}

消息发送接口
[AllowAnonymous]
[HttpPost]
public async Task SendTestMessageAsync()
{
var message = new DbContextTestMessage()
{
Data = ""
};
await _bus.PubSub.PublishAsync(message);
}

每调用一次,数据库连接就会增长一个

974299 monksoul 1578937227 百小僧 拥有者
回复 蔡宙航
4年前

终于看清楚了您的代码,您的用法错了,在异步(消费)中用法是不一样的,需要构建作用域范围,不然不能释放数据库对象。先看看这个

输入图片说明

https://dotnetchina.gitee.io/furion/docs/dbcontext-repository#945-在后台任务中使用

百小僧 任务状态待办的 修改为进行中 4年前
百小僧 负责人设置为百小僧 4年前
百小僧 添加了
 
漏洞
标签
4年前
百小僧 添加了
 
优化
标签
4年前
百小僧 里程碑设置为Furion 2021 4年前
百小僧 关联分支设置为master 4年前
百小僧 计划截止日期设置为2021-04-11 4年前
百小僧 计划开始日期设置为2021-04-10 4年前
百小僧 计划截止日期2021-04-11 修改为2021-04-10 4年前
百小僧 置顶等级设置为 4年前
百小僧 优先级设置为严重 4年前
百小僧 通过 dotnetchina/Furion Commit 9cb3c00任务状态进行中 修改为已完成 4年前
百小僧 置顶等级 修改为不置顶 4年前

我刚刚优化了数据库上下文池和创建数据库上下文的代码:9cb3c00

经过我这边测试,已经没问题。我看看今晚是否发一个版本给您。或者您先拿源码版本测试看看。

按文档的解决方案,解决问题了。非常感谢!

我也更新了1.18.9了

蔡宙航-caizhouhangcc 蔡宙航
回复 百小僧 拥有者
4年前

已经测试了,问题解决了

百小僧 关联分支master 修改为未关联 2年前

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(3)
974299 monksoul 1578937227 蔡宙航-caizhouhangcc stop_lyy-stoplyy_303
C#
1
https://gitee.com/dotnetchina/Furion.git
git@gitee.com:dotnetchina/Furion.git
dotnetchina
Furion
Furion

搜索帮助