我有一个多线程C#应用程序,我需要每个线程都有一个活动连接。我不能使用连接池,除非有一种方法可以使用静态连接在多线程应用程序中准确地更新/插入多个表而不使用锁。当连接数大约为200时,它很好。连接不会超出此范围。但是当我需要2200多个连接时,连接数量会无限增长。
创建连接的代码 -
@"Data Source=Server-3-PC\SQLSERVER2012;Initial Catalog=****;Persist Security Info=True;User ID=****;Password=****;Pooling=false";
我正在使用 -
检查SSMS的连接sp_who2
答案 0 :(得分:1)
您有责任关闭所有打开的连接。无论您是否使用池,模式为创建连接,打开,将其用于一个或多个SqlCommands并关闭它。
关于池,启用池的连接在关闭之前不会被重用,此时连接在重新使用之前被重置。无论哪种方法,您仍然需要关闭连接。
对于影响连接池使用的多个线程,我不知道它是如何相关的。 SqlConnection不是线程安全的,因此您应该将给定连接的所有权分配给单个线程,或者确保一次只有一个线程访问它。无论哪种方式,只要在完成后关闭它,就不应该遇到连接池问题。
我理解,我不能说2k连接会发生什么,但我无法想象很多连接的开销是健康的。鉴于你最终会受到数据库或cpu的限制,我会考虑重新考虑我的设计。也许某种缓冲或委托允许更少的连接。
例如,我有一个处理入站EDI文件的应用程序,一次很多。每个文件都有大约50k条记录,需要在数据库中进行更新。我没有执行50,000个命令,每个文件只有一个连接,而是有一个读取器,它会产生排队等待以后更新的更改。
读者创建了5000个左右的更新后,队列会创建一个数据表并将其作为参数传递给存储过程。这允许一个往返,一个事务和一个连接来处理来自许多文件的5000个更新。我们从每秒200次更新到每秒17,000次更新。
答案 1 :(得分:0)
我找到了答案。在Parallel循环中创建连接和关闭是不可靠的。连接应始终在循环外部创建,在内部使用和在外部封闭。
谢谢大家调查。
为了更好地解释这一点,这有效 -
Parallel.For(0,NumSymWatching , x =>
{
String conString = @"Data Source=TEJ-HP\SQLSERVER2012;Initial Catalog=DRMinutesData;Persist Security Info=True;User ID=sa;Password=sql;Pooling=false;";
SqlConnection hConnectionBars = new SqlConnection(conString);
hConnectionBars.Open();
SqlCommand hCommandBars = new SqlCommand();
hCommandBars.Connection = hConnectionBars;
BuildHistoricalBarData(A[x], B[x], beginFilterTimeMinutes, hCommandBars);
hConnectionBars.Dispose();
hConnectionBars = null;
});
以您希望的方式打开,使用和关闭连接。但是,如果在BuildHistoricalBarData方法中创建连接,它将继续增长。
此处未使用池的原因是“A”是指向不同表的项数组。即使它是同一个表,也会更改hCommandBars(通过并行运行的线程),如果不使用锁,就无法执行准确的插入/更新操作。然后锁会减慢它的速度。