【问题标题】:Unable to connect to SQL Server session database无法连接到 SQL Server 会话数据库
【发布时间】:2010-09-30 22:31:16
【问题描述】:

我的 asp.net 应用程序每天都能正常工作。 直到上个月,我的网络开始出现 2-3 次 Sqlsession 状态服务器问题 关注:

块引用 System.Web.HttpException 引发了“System.Web.HttpException”类型的异常。在 System.Web.HttpAsyncResult.End() 在 System.Web.SessionState.SessionStateModule.EndAcquireState(IAsyncResult ar) 在 System.Web.HttpApplication.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) ============ ======================================= 异常:System.Web.HttpException 无法连接到 SQL服务器会话数据库。在 System.Web.SessionState.SqlSessionStateStore.ThrowSqlConnectionException(SqlConnection conn, Exception e) 在 System.Web.SessionState.SqlSessionStateStore.SqlStateConnection..ctor(SqlPartitionInfo sqlPartitionInfo) 在 System.Web.SessionState.SqlSessionStateStore.GetConnection(String id, Boolean& usePooling ) 在 System.Web.SessionState.SqlSessionStateStore.DoGet(HttpContext context, String id, Boolean getExclusive, Boolean& locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actionFlags) 在 System.Web.SessionState.SqlSessionStateStore.GetItemExclusive(HttpContext context, String id, Boolean&locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actionFlags) 在 System.Web.SessionState.SessionStateModule.GetSessionStateItem() 在 System.Web.SessionState.SessionStateModule.PollLockedSessionCallback(Object state) =========== ======================================= 异常:System.InvalidOperationException 超时已过期。在从池中获取连接之前超时时间已过。这可能是因为所有池连接都在使用中并且达到了最大池大小。在 System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) 在 System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) 在 System.Data.SqlClient.SqlConnection.Open() 在 System.Web.SessionState。 SqlSessionStateStore.SqlStateConnection..ctor(SqlPartitionInfo sqlPartitionInfo)

然后我开始查看我的会话数据库服务器并在我的 sql 客户端中执行“exec sp_who”,结果中发现了很多 AspState 操作记录。

我不知道是什么导致了这种问题,因为我们确实没有改变任何严重的事情 在 out 应用程序中,仅修复了一些错误。

以下是我的 Web 应用程序环境的详细信息:

asp.net 3.5(从 1.1 转换)...在 2 个服务器场,会话状态为 sqlmode。

有没有人知道这个问题或对调查有任何想法? 谢谢

【问题讨论】:

    标签: c# asp.net sql-server session-state


    【解决方案1】:

    自从这篇文章首次提出以来已经有一段时间了,但我最近在生产环境中遇到了这个确切的问题,并认为它将来可能对其他人有用。

    我们有一个在 .NET 4.5.2 上运行的 ASP.NET MVC Web 应用程序,在两个节点之间进行负载平衡。该应用程序配置为将会话存储在 SQL Server 2012(版本 11.0.5058.0)上的 ASPState 数据库中。我们遇到了间歇性超时:

    异常信息: 异常类型:HttpException 异常消息:无法连接到 SQL Server 会话数据库。 超时已过。在从池中获取连接之前超时时间已过。这可能是因为所有池连接都在使用中并且已达到最大池大小。

    我认为,此处有关确保代码库中没有其他连接泄漏的一些答案具有误导性。为每个不同的连接字符串创建一个连接池,因此对与其他数据库的连接的任何修复都不会对会话状态数据库产生有益的影响。

    我们通过两个更改解决了这个问题:

    1. 通过覆盖 web.config 文件中连接字符串中的默认值 100 来提高最大池大小:

        sqlConnectionString="data source=SERVERNAME;Initial Catalog=AspState;user id=AspStateUser;password=xxxxx;App=xxxx; Max Pool Size=200;" 
      
    2. 很明显,AspState 数据库是使用 .NET 2.0 命令行创建的,重要的是,dbo.DeleteExpiredSessions SP 存在已知的阻塞问题。为了使问题更加复杂,该作业被配置为每分钟执行一次此过程。 AspState 数据库是使用 .NET 4.0 命令行重新创建的,如下所示:

    C:\Windows\Microsoft.NET\Framework\v4.0.30319>aspnet_regsql.exe -ssadd - sstype c -S OURSERVERNAME -d "AspState" -E

    关键的是,后来的版本包括一个性能改进版本的 DeleteExpiredSessions 过程,它包含一个游标,可以一次删除一个过期会话。我们还将相关作业的计划更改为每小时执行一次,而不是每分钟执行一次。

    【讨论】:

    • optimize-aspstate https://sqlperformance.com/2013/01/t-sql-queries/optimize-aspstate 怎么样? DeleteExpiredSessions SP NET 4.5 版本 don't try to delete ALL rows in one fell swoop, but don't play one-by-one whack-a-mole, either. Instead, delete n rows at a time in separate transactions – reducing the length of blocking and also minimizing the impact to the log
    • dbo.TempResetTimeout Every time a page is loaded (and, if the web app hasn't been created correctly, possibly multiple times per page load), the SP dbo.TempResetTimeout is called, ensuring that the timeout for that particular session is extended as long as they continue to generate activity. On a busy web site, this can cause a very high volume of update activity against the table dbo.ASPStateTempSessions 查看:optimize-aspstatehttps://sqlperformance.com/2013/01/t-sql-queries/optimize-aspstate
    • 就我而言,我没有 DB AspState。我使用给定的命令创建了数据库,它起作用了。
    【解决方案2】:

    不确定是否有人仍在查看此线程,但我发现了一篇有趣的文章,内容是关于大型会话状态和大量并发会话在删除数据时导致问题(当会话不再有效时)。尽管这里的信息有点过时,但可能值得研究。这是链接:http://msmvps.com/blogs/greglow/archive/2007/02/04/improving-asp-net-session-state-database-performance-by-reducing-blocking.aspx

    【讨论】:

    【解决方案3】:

    当开发人员使用大量 SqldataReader 获取数据以构建某种仪表板时,我已经看到这个确切的错误发生,但即使他将命令行为设置为 CloseConnection,他也从未关闭过他的数据读取器。一旦他这样做了(通过使用块的封闭),这些就消失了。同样,这可能不是问题的实际原因,但连接池耗尽通常表明连接没有正确关闭。

    【讨论】:

      【解决方案4】:

      这听起来确实像是您用尽了池中所有可用连接的情况。浏览您的代码并确保像这样设置您的数据库连接:

      using (SqlConnection cn = new SqlConnection(connectionString))
      {
          using (SqlCommand cm = new SqlCommand(commandString, cn))
          {
              cn.Open();
              cm.ExecuteNonQuery(); // or fill a dataset, etc.
          }
      }
      

      一旦退出这个“using”语句,连接就会自动关闭。

      这样做会清除应用程序中的所有其他数据库连接,并且状态服务器连接将能够在需要时进行连接。

      【讨论】:

      • 为每个唯一的连接字符串创建一个连接池,因此修复任何针对其他数据库的潜在连接泄漏肯定不会影响 Asp 会话状态数据库?
      【解决方案5】:

      如果这里的答案都不起作用,请查看<configuration><sessionState> 中的connectionString。在我的情况下,我更新了<configuration> 中的连接字符串,但不是在会话状态下指向不同的 SQL 服务器。

      只需在<sessionState> 中指定正确的连接字符串即可解决同样的错误。

      【讨论】:

      • 就是这样!感谢他的提示!
      【解决方案6】:

      您的负载增加了吗?您可能有很多连接,因为您有更多的用户使用该系统。

      您可以做的一件事是优化会话使用。您可以指定页面是使用会话状态还是仅进行读取。如果您有不使用或不修改会话的页面,这可以节省大量资金。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多