C#SqlConnections使用了整个连接池
我已经编写了一个服务,它偶尔必须经常轮询数据库。通常我会使用C#SqlConnections使用了整个连接池,c#,multithreading,sqlconnection,C#,Multithreading,Sqlconnection,我已经编写了一个服务,它偶尔必须经常轮询数据库。通常我会使用SqlDataAdapter创建一个新的SqlConnection,然后像这样启动: var table = new DataTable(); using(var connection = new SqlConnection(connectionString)) { connection.Open(); using(var adapter = new SqlDataAdapter(selectStatement, co
SqlDataAdapter
创建一个新的SqlConnection
,然后像这样启动:
var table = new DataTable();
using(var connection = new SqlConnection(connectionString))
{
connection.Open();
using(var adapter = new SqlDataAdapter(selectStatement, connection))
{
adapter.Fill(table);
}
}
但是,在高负载情况下(可能每周发生一次),服务可能会实际耗尽整个连接池,并且服务会记录以下异常
System.InvalidOperationException:超时已过期。从池中获取连接之前经过的超时时间。发生这种情况的原因可能是所有池连接都在使用中,并且已达到最大池大小
服务中的多个线程必须为各种查询访问SQL server,我希望尽可能多的线程并行运行(这显然有时效果太好)
我考虑了几种可能的解决方案:
- 我考虑过增加连接池的大小,但是这可能会延迟问题的解决李>
- 然后,我考虑为服务使用一个连接,并在服务运行的其余部分保持该连接的打开状态,这可能是一个简单的选择,但是它将保持连接的打开状态,即使没有工作负载要做,并且必须处理服务器等的连接重置。我不知道这样做的效果
- 最后,我考虑实现我自己的池,它管理并发连接的数量,并将线程保持在等待状态,直到有空闲的插槽
推荐的程序是什么,或者有没有最佳实践方法来处理这个问题?好吧,最终的解决方案并不理想(在SQL Server端解决了这个问题),所以我最后检查了作业队列系统中的并发连接数 该服务现在不会为文档生成创建另一个线程,除非它能够保证连接池实际可用。SQL server上的坏瓶颈仍然存在,但是该服务现在不再生成异常 当然,缺点是,当SQL Server上执行某些阻塞查询时,队列会变长,这可能会将文档生成延迟一两分钟。因此,这不是一个理想的解决方案,而是一个可行的解决方案,因为延迟并不重要,因为文档不是直接需要的,而是为了存档而存储的
更好的解决方案是在SQL Server端进行修复。首先,仔细检查并三次检查是否有连接泄漏。然后运行SQL profiler并确定您是否真的有多个长时间运行的查询。所有连接都使用
和包装。在这种情况下,瓶颈是SQL server。当两个服务都有大量工作要做,同时有人在SQL Server上运行长阻塞查询时,就会发生这种情况。实际上,与其说服务的查询花费的时间太长,不如说是另一个查询导致了SQL Server上的死锁。问题是,我无法避免这些死锁查询,因为原来的DB程序员。。。假设我想对他说几句话,我不想写下来。所以我必须等待服务器为我解决死锁。。。在“坏主意”解决方案部分中,基本上涵盖了您的两个想法。(增加池大小并设置大量超时)@Damien_不信者是的,他们在我写下他们的时候感觉不对劲。最后一个问题困扰着我?您的服务是否一直在运行相同的查询?顺便问一下,你所说的服务到底是什么意思?执行此查询需要多长时间?它返回的数据集更改的可能性有多大?