1

我有一个最多由 10 个客户端调用的 Web 服务。该网络服务由 7 个不同的 asmx 页面组成,每个页面有大约 100-200 个功能。

所有这些函数都针对 MSSQL2005 或 MS SQL2000 数据库工作。一天中的某些时段,来自客户端的流量很大,似乎我在 sql-server 上的连接用完了,导致所有客户端停止。

在每个函数中,我打开一个连接,做一些事情然后关闭连接,有时有事务,有时没有。

在服务器上,我看到它创建了很多连接,我不知道为什么它们不会消失,但即使在功能完成后仍然存在。所以我可以确定我的 10 个客户不时创建超过 80 个连接。有时它们中的一些会消失,有时它们在使用数小时后仍然存在。那里有某种池化吗?

问题 1:是否有另一种方法来处理我应该使用的连接,例如每个 Web 服务全局连接或任何其他方式?

问题 2:如果可以处理每个函数的连接,那么为什么它不关闭服务器上的连接,使打开的连接列表一直越来越大,直到我摆脱连接错误?

这个问题与我的另一个问题有关,但不一样:奇怪的 SQL2005 问题。“SqlConnection 不支持并行事务”

我现在将其范围缩小到“失去连接”错误。

4

3 回答 3

4

我同意关于重构的评论,但这不是这里的相关问题。

你绝对应该在每个函数中使用一个连接,听起来你没有正确处理它们。假设数据库操作包含在您正在调用的函数中,您的代码应如下所示:

using (SqlConnection connection = <connection code>)
{
  using (SqlCommand command = <command code>)
  {
    // Execute.
  }
}

在服务器端,连接将保持打开状态。默认情况下,SqlConnection 类启用连接池,因此您将看到连接在服务器端打开。

这种行为是正常的,应该是可以预料的。

于 2009-01-06T21:27:11.293 回答
3

您实际上看到了正在运行的连接池。这在 .Net 2+ 到 SQL 2005 中默认发生(不确定其他版本)。

连接池意味着 .Net 将为您打开一些连接,以便在您下次需要连接时减少开销。CLR 可以只为您提供一个已经打开(并已清理)的连接,这比直接重新连接到数据库要快几百倍。当您调用 connection.Close() 时,您只是将连接交还给池以进行回收。

每个单独的安全上下文连接都存在一个池 - 这意味着使用相同 SQL 安全性建立的所有连接将共享一个池,而如果您使用 Windows 身份验证,则每个连接的单独用户都将拥有自己的池。

您看到问题是因为您达到了 100 个连接 - 池中的默认最大数量(默认最小值为 0)。此时,池将无法提供另一个连接,直到一个连接被回收,因此应用程序将挂起或超时。您需要更改连接字符串以包含更高的最大数量(并且还要考虑减少连接)。

于 2009-01-06T22:02:02.923 回答
0

那么这就是一个 Web 服务中的 700-1400 个函数?对我来说听起来太大了。是时候重构了。

我不知道页面和网络服务之间的联系是什么。我通常将它们视为 XML 消息传递端点,完全独立于使用它们的客户端。

于 2009-01-06T20:04:34.813 回答