我在 .netcore 中托管了服务,它运行几个每秒执行 SQL 查询的函数。在运行应用程序一段时间它崩溃时,我知道它耗尽了所有连接池的问题并且我没有正确处理连接。我知道我需要打开和关闭连接。
dbcontext 未处理的异常:System.InvalidOperationException:超时已过期。在从池中获取连接之前超时时间已过。这可能是因为所有池连接都在使用中并且达到了最大池大小。
我面临的问题是我正在使用DBContext
它自动获取并为我打开数据库连接,我不必明确告诉我打开连接,但是我该如何关闭连接?每个Scope
?
public class DBChangeService : DelegatingHandler, IHostedService
{
private Timer _timer;
public SqlDependencyEx _sqlDependency;
private readonly IHubContext<SignalServer> _hubcontext;
private readonly IServiceScopeFactory _scopeFactory;
public DBChangeService(IHubContext<SignalServer> hubcontext, IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
_hubcontext = hubcontext;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_timer = new Timer(Heartbeat, null, 0, 1000);
return Task.CompletedTask;
}
public async void Heartbeat(object state)
{
await _hubcontext.Clients.All.SendAsync("SBSystemBrodcasting", SBSystemApps());
await _hubcontext.Clients.All.SendAsync("SBUserBrodcasting", SBNonSystemApps());
}
public List<SomeModel> SBSystemApps()
{
using (var scope = _scopeFactory.CreateScope())
{
var _DBcontext = scope.ServiceProvider.GetRequiredService<PlatformStatusContexts>();
var result = _DBcontext.SomeModels.FromSql((
@"SELECT
a.app_guid as AppGuid,
a.name as AppName,
a.state as AppState,
a.created_at as AppCreatedAt,
a.updated_at as AppUpdatedAt,
a.foundation as AppFoundation,
s.name as SpaceName,
o.name as OrgName
FROM
apps as a
INNER JOIN
spaces as s ON a.space_guid = s.space_guid
INNER JOIN
organizations as o ON s.org_guid = o.org_guid
where s.name = 'system' and o.name = 'system' and a.foundation = 2")).ToList();
return result;
}
}
public List<SomeModel> SBNonSystemApps()
{
using (var scope = _scopeFactory.CreateScope())
{
var _DBcontext = scope.ServiceProvider.GetRequiredService<PlatformStatusContexts>();
var result = _DBcontext.SomeModels.FromSql((
@"SELECT
a.app_guid as AppGuid,
a.name as AppName,
a.state as AppState,
a.created_at as AppCreatedAt,
a.updated_at as AppUpdatedAt,
a.foundation as AppFoundation,
s.name as SpaceName,
o.name as OrgName
FROM
apps as a
INNER JOIN
spaces as s ON a.space_guid = s.space_guid
INNER JOIN
organizations as o ON s.org_guid = o.org_guid
where s.name != 'system' and o.name != 'system' and a.foundation = 2")).ToList();
return result;
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
//Timer does not have a stop.
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
}
启动:
services.AddDbContext<PCFStatusContexts>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
连接字符串:
"DefaultConnection": "Server=address,port;Database=dbname;User Id=uname;Password=password;Trusted_Connection=false;MultipleActiveResultSets=true;"
更新:
数据库上下文:
public partial class PlatformStatusContexts : DbContext
{
public PlatformStatusContexts()
{
}
public PlatformStatusContexts(DbContextOptions<PlatformStatusContexts> options): base(options)
{
}
public virtual DbSet<Apps> Apps { get; set; }
public virtual DbSet<Organizations> Organizations { get; set; }
public virtual DbSet<Spaces> Spaces { get; set; }
public DbQuery<SomeModel> SomeModels { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//model builder for each table
}
}