在Web服务中处理sql连接的最佳方法?

时间:2009-01-06 19:25:42

标签: sql-server connection-pooling sqlconnection

我有一个由最多10个客户端调用的Web服务。 Web服务由7个不同的asmx页面构成,每页有大约100-200个函数。

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

在每个功能中,我打开一个连接,做这些事情,然后关闭连接,有时候有时没有交易。

在服务器上,我看到它创建了很多连接,我不知道为什么它们不会消失,但即使在功能完成之后也会停留在那里。所以我可以说我的10个客户不时创建80多个连接。有时它们中的一些会消失,有时它们在使用后仍然存在几个小时。那里有什么样的聚会吗?

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

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

这个问题与我的其他问题有关,但不一样:Strange SQL2005 problem. "SqlConnection does not support parallel transactions"

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

3 个答案:

答案 0 :(得分:4)

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

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

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

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

这种行为是正常的,应该是预期的。

答案 1 :(得分:3)

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

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

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

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

答案 2 :(得分:0)

那么单个Web服务中的700-1400功能呢?听起来对我来说太大了。重构的时间。

我不知道页面和Web服务之间的联系是什么。我通常认为它们是XML消息传递端点,与使用它们的客户端完全分开。