为什么我有时无法获得数据库连接?

时间:2014-06-10 21:12:19

标签: c# sql-server-2012 entity-framework-5

在生产系统上,我偶尔会在日志中发现以下错误:

  

超时已过期。从池中获取连接之前经过的超时时间。这可能是因为所有池连接都在使用中并且达到了最大池大小。

为了解决这个问题,我将最大池大小增加到了极高的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
}

4 个答案:

答案 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()方法以强制"强制"垃圾收集,但正如文档所述,这可能会导致性能问题(因此 可能 是一个选项,或者它可能会为另一个问题交换一个问题)。