.NET SQL连接池超出最大大小问题测试与技术咨询
解决.NET SQL连接池超出最大大小的问题
老哥,你这个问题其实是典型的连接泄漏导致的连接池耗尽——你的代码里循环创建了100个SqlConnection,但只给SqlCommand和SqlDataReader加了using,却没给SqlConnection加using(或者手动调用Dispose/Close),导致打开的连接一直占着连接池的名额,到第51次循环时,连接池里的50个名额全被占满,自然就报超出最大大小的错误了。
核心原因
SQL Server连接池的工作逻辑是:当你调用conn.Open()时,会从连接池里拿一个空闲连接;当你调用conn.Close()或conn.Dispose()时,连接会被归还给连接池复用。你的代码里打开连接后没有归还,连接池的50个名额很快就被耗尽了。
解决方案
1. 给SqlConnection加上using语句(最关键)
把SqlConnection也放进using块里,它会自动帮你释放连接并归还给连接池,这是.NET里处理IDisposable对象的标准做法。修正后的代码如下:
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++) { // 把SqlConnection放进using块,自动释放连接 using (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)}"); } } } } // 此处自动调用conn.Dispose(),连接归还给连接池 } }
2. 谨慎调整Max Pool Size(非必要不优先)
如果你的业务确实需要同时使用超过50个连接,可以把Max Pool Size调大(比如设为100),但这只是治标——如果存在连接泄漏,调大数值只是延迟报错的时间,最终还是会耗尽。所以先解决连接泄漏问题,再考虑调整这个参数。
3. 排查潜在的连接泄漏
如果生产环境遇到类似问题,可以用以下方式排查:
- 用SQL Server的
sys.dm_exec_connections视图查看当前的连接状态,筛选你的Application Name=JH的连接,看是否有大量未释放的连接; - 用.NET性能计数器(比如
SqlClient: Connection Pooling下的Number of Active Connections)监控连接池的活跃连接数,确认是否有持续增长的情况。
内容的提问来源于stack exchange,提问作者Jiho Han




