记录一次自己的BUG之旅(超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小)

编程语言:C#
业务场景:接收手环实时传送的坐标点数据,每5秒推送数据,接收数据,存入本地数据库。
数据库插入操作:SqlBulkCopy批量插入数据库
出错代码

SqlConnection connection = new SqlConnection(conn)
SqlBulkCopy sbc = new SqlBulkCopy(connection, SqlBulkCopyOptions.UseInternalTransaction);
sbc.DestinationTableName = tableName;
sbc.BatchSize = batchSize;
for (int i = 0; i < dataTable.Columns.Count; i++)
{
sbc.ColumnMappings.Add(dataTable.Columns[i].ColumnName, dataTable.Columns[i].ColumnName);
}
sbc.WriteToServer(dataTable);

报错提示:超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小
BUG解析:问题的原因是与数据库的连接没有关闭,而等待系统自动回收是需要时间的 (数据库默认的连接数是100),达到了数据库连接池的上限了。
此方法 是需要5秒调用一次,和数据库建立的又是短连接,短时间内就会到达链接数100,从而报错。
解决方法: 这些解决方法是从网上整理过来的 ,有些还没测试:
1、 及时使用Close()方法关闭,连接对象在Open后的操作都放在try块中,后面跟一个finally块:conn.Close();
2、使用using来自动释放资源
3、WEB.config 里面:在数据库连接加 Max Pool Size = 512;server=local;uid=;pwd=;database=2004;Max Pool Size = 512;">一劳永逸;
4、使用EF框架 进行数据库操作, savechange()方法同样是批量操作;(我是使用的这种方法进行改善的)

附:查询数据库的连接情况:(数据库SQL可直接执行)
SELECT [dec].client_net_address,
[des].[program_name],
[des].[host_name],
Count([dec].session_id) AS connection_count
FROM sys.dm_exec_sessions AS [des]
INNER JOIN sys.dm_exec_connections AS [dec]
ON [des].session_id = [dec].session_id
GROUP BY [dec].client_net_address,
[des].[program_name],
[des].[host_name]
ORDER BY [des].[program_name],
[dec].[client_net_address]

你可能感兴趣的:(记录一次自己的BUG之旅(超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小))