C# 连续运行应用程序上的SQL Server连接池
我有问题的连接拉与持续运行的程序。当我在任务中对数据库进行大量查询(每4分钟5次(查询3个表并将结果保存到一个表))时,就会出现问题。连接池的最大池连接大小已用完。奇怪的是,我在DB100上等待特定连接字符串/机器/用户条目的命令条目。我的理解是,等待命令意味着这个连接可以重用,但由于某种奇怪的未知原因,当从任务运行命令时,我无法重用可用的连接,他们只是不等待任何人,并且在一段时间后出现错误,我已达到最大池连接大小 迄今为止的假设:C# 连续运行应用程序上的SQL Server连接池,c#,sql-server,multithreading,connection-pooling,C#,Sql Server,Multithreading,Connection Pooling,我有问题的连接拉与持续运行的程序。当我在任务中对数据库进行大量查询(每4分钟5次(查询3个表并将结果保存到一个表))时,就会出现问题。连接池的最大池连接大小已用完。奇怪的是,我在DB100上等待特定连接字符串/机器/用户条目的命令条目。我的理解是,等待命令意味着这个连接可以重用,但由于某种奇怪的未知原因,当从任务运行命令时,我无法重用可用的连接,他们只是不等待任何人,并且在一段时间后出现错误,我已达到最大池连接大小 迄今为止的假设: 从tasks DB运行命令时,将其解释为无效,以重用可用连接
using System;
using System.Data.SqlClient;
using System.Threading;
using System.Threading.Tasks;
namespace Pooling
{
class Program
{
private static int connectionIterations;
private static string connectionString = "Data Source=localhost;Initial Catalog=localDB;Integrated Security=True";
static void Main(string[] args)
{
try
{
Iterations();
while(true)
{
ConnectionSnowball();
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private static void ConnectionSnowball()
{
Parallel.For(0, connectionIterations, i =>
{
try
{
Console.WriteLine($"Connection id: {i}");
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("SELECT 1 FROM test_table", connection);
connection.Open();
cmd.ExecuteNonQuery();
Thread.Sleep(600000);
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
});
}
private static void Iterations()
{
connectionIterations = 200;
}
}
}
我调试了你的代码,没有发现连接泄漏。您只是有一个连接池溢出。我为您检查了两种可能的解决方案 禁用池连接
private static string connectionString = "Data Source=localhost;Initial Catalog=localDB;Integrated Security=True;Pooling=False";
增加连接池
private static string connectionString = "Data Source=localhost;Initial Catalog=localDB;Integrated Security=True;Max Pool Size=200";
要测试在调用ConnectionSnowball()
之前、期间和之后连接的增加和减少方式,可以使用此SQL查询
select count(1) from sys.dm_exec_sessions where database_id = DB_ID(N'localDB')
有关连接字符串参数的详细信息
其他可能的解决办法是使用。对于此任务,这可能是一个更合适的解决方案,因为大量连接非常占用资源。似乎缺少释放/处置资源。您是否尝试过在SqlCommand周围使用进行
?根据查询持续时间的不同,连接数200可能会超过100。请注意,您无法通过从服务器查看来判断连接是否在池中且可供使用,或者连接是否正在由客户端使用但当前未提供命令。这段信息只存在于客户端——只要一个物理连接正被一个未经分解的SqlConnection
实例使用,它就在使用中;否则就不是了。若要查看客户端上是否存在资源泄漏,请创建一个转储文件,并分析SqlConnection
实例的堆以及使它们保持活动状态的GC根。@FrankNielsen我将尝试此方法。我认为这不能挂起SqlConnection,如果不使用。不过,这是事实。当您删除并行时,它将始终使用精确的一个连接,这意味着没有连接泄漏。当您切换到任务和连接时,从15 ie开始,比稳定和粗暴地上升,直到最大池大小。任务可能是问题所在。另一个不太可能检查的问题是,每次创建新连接时都使用相同的连接字符串(如中,字符对字符相同),因为这就是池连接的关键所在。