1.18.5
从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后,运行正常。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
比较了一下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
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);
}
每调用一次,数据库连接就会增长一个
终于看清楚了您的代码,您的用法错了,在异步(消费)中用法是不一样的,需要构建作用域范围,不然不能释放数据库对象。先看看这个
https://dotnetchina.gitee.io/furion/docs/dbcontext-repository#945-在后台任务中使用
按文档的解决方案,解决问题了。非常感谢!
登录 后才可以发表评论