【问题标题】:ASP.NET application opening WAY too many SQL connectionsASP.NET 应用程序打开太多 SQL 连接
【发布时间】:2023-03-23 17:14:01
【问题描述】:

我在 ASP.NET Webforms 4 应用程序的代码位上有问题。 我正在使用 SQL Server 2008 R2、IIS 7,该网站在单独的应用程序池中的 Windows Server 2008 R2 上运行(集成模式,.NET4,支持 32 位程序集)。

以下代码存在问题:

Dim sqlCmd = New SqlClient.SqlCommand
With sqlCmd
    Using sqlConnectionToUse As SqlClient.SqlConnection = GetActiveConnexion(pstrConnectString), _
        vAdaptor As New SqlClient.SqlDataAdapter

            .Connection = sqlConnectionToUse

            .CommandText = pstrSQL 'function parameter

            vAdaptor.SelectCommand = sqlCmd
            'query1: SELECT somecolumn FROM table WHERE somecolumn '' ==> opens a new connection in SQL Server
            'query2: SELECT someothercolumn FROM anothertable WHERE someothercolumn 23 ==> uses my WebSite process active connection
            vAdaptor.Fill(vDataSet)
    End Using
End With

更新: GetActiveConnexion() 方法在我的例子中只执行以下代码:

Return New SqlClient.SqlConnection("my connection string obtained from the web.config file")

当我运行 query2 时,一切顺利,ASP.NET 应用程序使用应用程序池的打开连接,我在数据集中得到了我的结果。

但是,每当我运行 query1 时,都会在 SQL 服务器中打开一个新连接(我可以看到它显示在 SSMS 的活动监视器中),并且这个连接保持打开状态。问题是,如果我运行这个 query1 100 次,我会达到连接池的限制,并且会发生非常糟糕的事情。我仍然在数据集中得到结果,可以使用它们等等...... 新连接是在调用 vAdaptator.Fill() 时创建的。

有什么想法吗?

非常感谢您的宝贵时间。 (PS:抱歉英语不好)。

这里是 C# 中的代码,适合喜欢的人:

object sqlCmd = new SqlClient.SqlCommand();
using (SqlClient.SqlConnection sqlConnectionToUse = GetActiveConnexion(pstrConnectString)) {
    using (SqlClient.SqlDataAdapter vAdaptor = new SqlClient.SqlDataAdapter()) {

        sqlCmd.Connection = sqlConnectionToUse;

        sqlCmd.CommandText = pstrSQL; //function parameter

        vAdaptor.SelectCommand = sqlCmd;
        //query1: SELECT F10_ID FROM FIN_MONTANT_TT_F10 WHERE F10_ID_TT_F19 = '' ==> opens a new connection in SQL Server
        //query2: SELECT A48_ID FROM ADH_EPARTICIPANT_ADMIN_A48 WHERE A48_ID=23 ==> uses my WebSite process active connection
        vAdaptor.Fill(vDataSet);
    }
}

【问题讨论】:

  • 连接字符串总是一样的吗?可以看出,query1 在 where 子句中使用了一个测试字段,如果不存在适当的索引,可能会导致一些麻烦......
  • 我想我们需要看看GetActiveConnexion() 的逻辑——你是否明确地打开/关闭了要使用的连接?
  • 连接池依赖于完全相同的连接字符串。您是否根据 query1 检查了您的 pstrConnectString 变量?执行 query1 时的确切 pstrConnectString 是什么?
  • 我刚刚添加了 GetActiveConnexion 逻辑,在我的情况下非常简单。不,我没有明确打开关闭连接。 using 这样做(在适配器和连接上调用 dispose)以及 vAdaptor.Fill(打开和关闭连接)。
  • 连接字符串始终相同。我从 web.config 文件中得到它,所以我不应该改变。我会继续检查的。

标签: asp.net sql-server-2008 connection-pooling application-pool


【解决方案1】:

您的SqlCommand 实例应该包装在 using 块中,因为它是一次性的。这可能是你问题的根源。

using (SqlClient.SqlConnection sqlConnectionToUse = GetActiveConnexion(pstrConnectString)) 
{
    using (SqlCommand sqlCmd = sqlConnectionToUse.CreateCommand())
    {
        using (SqlClient.SqlDataAdapter vAdaptor = new SqlClient.SqlDataAdapter()) 
        {
            ...
        }
    }
}

或VB

Using sqlConnectionToUse As SqlClient.SqlConnection = GetActiveConnexion(pstrConnectString)
    Using sqlCmd As SqlCommand = sqlConnectionToUse.CreateCommand()
        Using vAdaptor As New SqlClient.SqlDataAdapter()
                ...
        End Using
    End Using
End Using

【讨论】:

  • 刚刚补充说,我的问题仍然存在,对于代码来说效果更好。编辑:虽然我的使用顺序不同,但我会再试一次。也许 sqlConnectionToUse.CreateCommand() 可以提供帮助。
  • 上面的代码应该不会导致问题,你确定你不只是看到连接池的结果吗?处理完 SqlCommand 后它还会增长吗?
  • 确实有帮助。但是,我仍然在 15 个连接左右。我在这个代码块周围使用了一个同步锁(我忘记在代码 sn-ps 中添加它),这可能是我还有一些线程等待执行代码,因此保持连接打开?但是,Usings 位于同步锁内(因此,如果锁定,则不应打开连接)。
  • 15 很可能是连接池,如果它没有像您可能还好之前那样增长。仅当您在创建连接后锁定时,同步时钟才是问题。如果您只是将此代码包装在同步锁实现中,那应该没问题(显然,您应该有充分的理由使用同步锁)。
  • 我让代码运行多次,15个连接是稳定的(实际上只有12个连接,其中2个是SSMS查询,1个来自另一个应用程序)。但是,在我更改代码后(即在其他页面上导航,执行不会导致假定连接池的其他请求),这 12 个连接保持活动状态。我应该为此担心还是应该去阅读更多关于 MSDN 上的连接池的文章?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
相关资源
最近更新 更多