.NET SQL 连接超过最大池大小

Jih*_*Han 1 .net sql-server ado.net

我编写了一个简单的应用程序来测试连接字符串中的 Max Pool Size=50。

    static void Test1()
    {
        string connectionString = @"Server=.;Database=appsdb;Trusted_Connection=True;Application Name=JH;Max Pool Size=50";
        for (int i = 1; i <= 100; i++)
        {
            var conn = new SqlConnection(connectionString);
            conn.Open();
            using (var cmd = new SqlCommand("select newid()", conn))
            {
                using (var r = cmd.ExecuteReader())
                {
                    while (r.Read())
                    {
                        Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] {i} - {r.GetGuid(0)}");
                    }
                }
            }
        }
        Console.WriteLine("Done");
        Console.ReadLine();
    }
Run Code Online (Sandbox Code Playgroud)

我让它运行了 51 个连接,最初预计第 51 个连接会失败,但事实并非如此。在第 71 次
连接 时始终失败,但有以下例外:

System.InvalidOperationException:“超时已过期。从池中获取连接之前超时时间已过。发生这种情况可能是因为所有池连接都在使用中并且达到了最大池大小。

sp_who当我用(或)检查时,sp_who2我可以看到正好有50 个连接。这令人费解。
我可以理解 .NET 是否以某种方式让您重用连接,但为什么在 71 层呢?
为什么只允许额外的 20 个(逻辑)连接?为什么不是19或47?

Mar*_*ell 5

看来您没有保持循环迭代之间的连接for。这意味着每次迭代循环时for,上一次迭代的连接都符合垃圾回收的条件,这会将底层连接释放回池中。所以:大概发生了垃圾收集。要测试这一点:保持使用的连接可达 - 将它们放在列表或类似的列表中。例如:

var list = new List<SqlConnection>();
for (int i = 1; i <= 100; i++)
{
    var conn = new SqlConnection(connectionString);
    list.Add(conn);
    conn.Open();
    // ... etc removed
}
GC.KeepAlive(list);
Run Code Online (Sandbox Code Playgroud)