0

我有一个多线程 C# 应用程序,我需要每个线程都有一个活动连接。我不能使用连接池,除非有一种方法可以使用静态连接在多线程应用程序中准确地更新/插入多个表而不使用锁。当连接数在 200 左右时,没问题。连接不会超出此范围。但是当我需要 2200+ 个连接时,连接数会无限增长。

创建连接的代码 -

 @"Data Source=Server-3-PC\SQLSERVER2012;Initial Catalog=****;Persist Security Info=True;User ID=****;Password=****;Pooling=false";

我正在使用 - 检查来自 SSMS 的连接 -

sp_who2
4

2 回答 2

1

您有责任关闭您打开的任何连接。不管你是否使用池化,模式都是创建一个连接,打开,将它用于一个或多个 SqlCommands 并关闭它。

关于池化,启用池化的连接在关闭之前不会被重新使用,此时连接会在重新使用之前被重置。无论哪种方法,您仍然需要关闭连接。


关于影响连接池使用的多个线程,我看不出这有什么关系。SqlConnection 不是线程安全的,因此您应该将给定连接的所有权分配给单个线程或确保一次只有一个线程访问它。无论哪种方式,只要在完成后关闭它,就不会遇到连接池问题。


我理解,我不能说 2k 连接会发生什么,但我无法想象这么多连接的开销是健康的。鉴于您最终会受到数据库或 CPU 的限制,我会考虑重新考虑我的设计。也许是某种允许更少连接的缓冲或委托。

例如,我有一个处理入站 EDI 文件的应用程序,一次处理很多。每个文件有大约 50k 条记录,需要在数据库中进行更新。我没有使用每个文件一个连接执行 50,000 个命令,而是有一个阅读器,它产生的更改会排队等待以后更新。

在读者创建了大约 5000 次更新后,队列会创建一个数据表并将其作为参数传递给存储过程。这允许一次往返、一次事务和一次连接来处理来自许多文件的 5000 次更新。我们从每秒 200 次更新增加到每秒 17,000 次更新。

于 2012-11-18T18:21:05.097 回答
0

我找到了答案。在并行循环中创建连接和关闭是不可靠的。连接应始终在循环外部创建,在内部使用并在外部关闭。

谢谢大家的调查。

为了更好地解释这一点,这有效 -

 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 也会被更改(通过并行运行的线程),并且您永远无法在不使用锁的情况下执行准确的插入/更新操作。锁会减慢它的速度。

于 2012-11-21T03:47:17.637 回答