在生产系统上,我偶尔会在日志中发现以下错误:
超时已过期。从池中获取连接之前经过的超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。
为了解决这个问题,我将最大池大小增加到了极高的10,000:
的connectionString =“元数据= RES:// /MyEntities.csdl|res:// /MyEntities.ssdl|res://*/MyEntities.msl;provider=System.Data.SqlClient ; provider connection string =“data source = localhost; initial catalog = MyDb; integrated security = True; MultipleActiveResultSets = True; Max Pool Size = 10000; App = My Service”“
但问题仍然存在。除了连接池被最大化之外,还有什么其他原因导致此错误?
编辑:在其他人建议之前,每当我打开与DB的连接时,执行总是使用using(...) { }
块,例如:
using (var db = new MyEntities())
{
// do stuff
}
答案 0 :(得分:0)
您如何连接数据库?
拥有大量连接会使您的应用程序延长使用寿命,但根本问题可能是您没有正确释放所有连接。打开后检查您是否正在关闭连接。例如
using (SqlConnection myConnection = new SqlConnection(ConnectionString))
{
... perform database query
}
完成后会自动关闭连接。
答案 1 :(得分:0)
始终.Close()
连接。这意味着总是这样做非常重要。如果你不这样做,你做错了。任何应用程序都可以溢出ConnectionPool
。因此,请确保每次打开它时都调用.Close()
以清除池。不要依赖GC来关闭连接。
确保在try块中调用.Close()
,也在catch块中调用。
答案 2 :(得分:0)
通常会发生这种情况,因为您在代码中关闭了,例如,DataReader,但您没有关闭其关联的连接。 在上面的代码中,根据您的目的,有两种解决方案。
1 /完成后明确关闭连接。
connection.Close();
2 /使用Using块中的连接,这可以保证系统在代码退出块时处理连接(并将其关闭)。
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// Do work here; connection closed on following line.
}
答案 3 :(得分:-2)
根据我从其他来源like this MSDN page收集的内容,using (...) { }
块的垃圾收集不足以阻止您的应用程序耗尽连接。 William Vaughn的回复表明,通过Close()
方法显式清除连接比使用垃圾收集更快地将线程返回池中。
所以,虽然你没有做错任何事,因为using (...) { }
块是正确的编码,但它缺乏效率是让线程被绑定的时间太长。您也可以查看Collect()
方法以强制"强制"垃圾收集,但正如文档所述,这可能会导致性能问题(因此 可能 是一个选项,或者它可能会为另一个问题交换一个问题)。