多年来,我在连接到SQL服务器的所有Web应用程序上遇到了非常奇怪的问题。
问题在于,如果数据库服务器出现问题(服务器重启或其他问题),de web app就会在此时停止工作,即使数据库服务器处于活动状态且之后也很好。
每个ADO.NET操作(ExecuteNonQuery,CreateReader,BeginTransaction,...)都会因 InvalidOperationException 而失败:“无效操作。连接已关闭 ”。似乎对 SqlConnection.Open()的调用从应用程序池中检索了一个已关闭的连接!
根据文档,连接池应该自动从连接池中删除断开的连接,但是显然关闭连接不被视为“切断”,因此调用 SqlConnection.Open()愉快地返回一个已关闭的连接,假设它是打开的,而不检查它。
我目前的解决方法是在打开连接后立即检查连接状态:
using (SqlConnection connection = new SqlConnection( connectionString ))
{
connection.Open();
if (connection.State != ConnectionState.Open)
{
SqlConnection.ClearAllPools();
connection.Open();
}
// ...
}
这种解决方法似乎现在有效,但我觉得这样做并不舒服。
所以我的问题是:
答案 0 :(得分:12)
我之前对连接池进行了一些类似的研究,原因略有不同,但希望会有所帮助。我找到的是:
连接会自动从池中删除,我的发现是这通常发生在上次使用后的几分钟内。因此,它可能是一个计时问题 - 它们正在被清除,但是在尝试再次重用连接之前不会这样。
这些是我当时看到的一些文章:
Sql Server Google Group
Using Connection Pooling in ASP.NET
修改强>
这种糟糕的连接永远存在于池中听起来很奇怪 - 你确定它确实存在,它不只是多个不良连接吗?如果您确定,那么听起来您的代码中没有正确释放这些连接。 This是我刚才读过的另一篇非常好的文章,它说(引用):
自动刷新连接
如果合并的连接仍然存在 “封闭但可重复使用”的状态 4到8分钟之间(一个间隔 随机选择)连接 汇集机制关闭物理 连接并丢弃池 连接。这是除非数量 其余的连接更大 比最小连接 为池配置(默认值 是0)。请注意,连接必须 已被申请关闭 (然后释放回游泳池) 它可以自动化 发布。如果你不关闭 代码中的连接或孤立的 连接对象,池 机制什么都不做。不在这里 没有ConnectionString参数 更改超时值。
答案 1 :(得分:2)
我们在使用ADO的C ++中看到了同样的问题。几年前,在使用Microsoft支持后,我们还在代码中实现了类似的重试逻辑,并重置了解决问题的连接池。
如果有更好的解决方法,Microsoft支持人员要么不知道,要么不共享(当时无论如何)。