【问题标题】:Migrated from SQL Server CE to SQL Server, now WebSecurity causing SQL Timeouts从 SQL Server CE 迁移到 SQL Server,现在 WebSecurity 导致 SQL 超时
【发布时间】:2017-03-04 08:47:25
【问题描述】:

我们有一个使用 ASP.Net 网页构建的网站

我最近将数据库从 SQL Server CE 迁移到 SQL Server 2014。我使用本地计算机上的 SQL Server Compact Toolbox 执行此操作,然后将 .mdf 文件附加到我们的网站主机 SQL Server 实例。

一切都很好,网站似乎运行良好。然而,不久之后,我开始注意到像这样的间歇性异常:

System.Web.HttpUnhandledException (0x80004005):引发了“System.Web.HttpUnhandledException”类型的异常。

System.Data.SqlClient.SqlException (0x80131904):超时。在操作完成之前超时时间已过或服务器没有响应。

System.ComponentModel.Win32Exception (0x80004005):等待操作超时

在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔 breakConnection,Action1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()
at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()
at System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte& value)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource
1 完成,Int32 超时,Task& 任务,布尔 asyncWrite)
在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,字符串方法)
在 System.Data.SqlClient.SqlCommand.ExecuteScalar()
在 WebMatrix.Data.Database.QueryValue(String commandText, Object[] args)
在 WebMatrix.WebData.DatabaseWrapper.QueryValue(String commandText, Object[] 参数)
在 WebMatrix.WebData.SimpleMembershipProvider.GetUserId(IDatabase db,字符串 userTableName,字符串 userNameColumn,字符串 userIdColumn,字符串 userName)
在 WebMatrix.WebData.SimpleMembershipProvider.GetUser(字符串用户名,布尔 userIsOnline)
在 System.Web.Security.Membership.GetUser(字符串用户名,布尔 userIsOnline)
在 WebMatrix.WebData.WebSecurity.GetUserId(字符串用户名)
在 WebMatrix.WebData.WebSecurity.get_CurrentUserId()
在 ASP._Page_Default_cshtml.c__DisplayClass5.b__3() 在 e:\web\givetoru\Default.cshtml:line 118
在 System.Web.WebPages.WebPageBase.c__DisplayClassb.b__9(TextWriter tw)
在 System.Web.WebPages.HelperResult.WriteTo(TextWriter writer)
在 System.Web.WebPages.WebPageBase.Write(HelperResult 结果)
在 e:\web\givetoru_SiteLayout.cshtml:line 184 中的 ASP._Page__SiteLayout_cshtml.Execute()
在 System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
在 System.Web.WebPages.WebPage.ExecutePageHierarchy(IEnumerable1 executors)
at System.Web.WebPages.WebPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.WebPages.WebPageBase.<>c__DisplayClass7.<RenderPageCore>b__6(TextWriter writer)
at System.Web.WebPages.HelperResult.WriteTo(TextWriter writer)
at System.Web.WebPages.WebPageBase.Write(HelperResult result)
at System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action
1 正文)
在 System.Web.WebPages.WebPageBase.PopContext()
在 System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext,TextWriter writer,WebPageRenderingBase startPage)
在 System.Web.WebPages.WebPageHttpHandler.ProcessRequestInternal(HttpContextBase httpContext)

ClientConnectionId:4f57f963-05e1-4429-946b-504e59e13050
错误号:-2,状态:0,类:11

在 System.Web.WebPages.WebPageHttpHandler.HandleError(Exception e)
在 System.Web.WebPages.WebPageHttpHandler.ProcessRequestInternal(HttpContextBase httpContext)
在 System.Web.WebPages.WebPageHttpHandler.ProcessRequestInternal(HttpContext 上下文)
在 System.Web.WebPages.WebPageHttpHandler.ProcessRequest(HttpContext 上下文)
在 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
在 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

在进行了一些挖掘之后,看起来它可能与像这样对 WebMatrix.WebData.WebSecurity 类的调用有关:

WebSecurity.CurrentUserId

有人对可能导致此问题的原因有任何想法吗?我需要对我的数据库做一些特殊的事情来防止这些超时吗?

更新 20170303 922AM CT

这是我的连接字符串(敏感数据已编辑)供参考:

<add name="StarterSiteEntities" connectionString="metadata=res://*/App_Code.ProductModel.csdl|res://*/App_Code.ProductModel.ssdl|res://*/App_Code.ProductModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=tcp:*****;initial catalog=*****;integrated security=False;Connection Timeout=30;user id=*****;password=****;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

<add name="StarterSite" connectionString="Data Source=tcp:****;Initial Catalog=****;User ID=****;Password=*****;Integrated Security=False;Connection Timeout=30;" providerName=
"System.Data.SqlClient" />

这是我的 _AppStart.cshtml 文件中初始化 WebSecurity DB 连接的行:

WebSecurity.InitializeDatabaseConnection("StarterSite", "UserProfile", "UserId", "Email", autoCreateTables: false);

【问题讨论】:

  • 只是一个快速的想法:WebMatrix.WebData.WebSecurity 处理 SimpleMembershipProvider。默认情况下,这可以使用与常规数据访问代码完全不同的连接字符串。因此,您可以检查是否有两个不同的连接字符串在使用中,并且在迁移到完整的 SQL Server 数据库时可能没有更新一个。
  • 这看起来像是一般的超时问题。如果重新启动 SQL Server,超时问题会消失吗? IE。是否只有在 SQL Server 运行一段时间后才会出现此问题?

标签: c# asp.net sql-server sql-server-ce asp.net-webpages


【解决方案1】:

这似乎是与 SQL Server 的正常连接问题。由于您的应用程序通常工作,我假设您的问题可能是您可能对常规数据访问代码和使用 SimpleMembershipProvider 的身份验证使用不同的连接字符串,仅当从数据库中查询任何与身份验证相关的数据时才会导致问题:

正如我在您的问题下方的评论中提到的,发生异常的WebMatrix.WebData.WebSecurity 使用SimpleMembershipProvider 处理身份验证。用于此的连接字符串可能与您用于常规数据访问代码的连接字符串完全不同,例如一个实体框架DataContext

因此,按照您的描述方式,我认为您很可能正在为 SimpleMembershipProvider 和您的 EF DataContext 使用两个不同的连接字符串(或任何您用于数据访问需求的连接字符串),也许是一个因为SimpleMembershipProvider 在迁移到完整的 SQL Server 数据库时没有更新。

我希望这至少会引导您朝着正确的方向前进。否则,也许您想共享您的 web.config,尤其是完整的 Membership 和 ConnectionString 配置。不过,请确保不要发布任何敏感数据:)

更新:

您发布的连接字符串看起来很好且相同。我在您的异常中遗漏了一点:它说Timeout expired,而如果真的是连接超时,它会说Connection timeout expired(至少在.NET Framework 4.5 或更高版本中,IIRC)。

因此,您应该检查是否可能遇到查询性能问题。您的自定义用户表中的UserName 上是否有索引,因为这是根据 StackTrace 查询的内容?而我承认,即使没有索引,用户表中没有任何复杂连接的单个查询似乎也不太可能运行超过 30 秒。但有时您可能会遇到数据库锁。

因此,接下来您可以将 SQL Server Profiler 附加到您的数据库并让它运行,直到您的应用程序中出现上述异常。然后检查此时 Profiler 中是否执行了任何长时间运行的查询。

【讨论】:

  • 感谢您的周到回复。我已更新我的问题以包含连接字符串。
  • @TodBirdsall 我刚刚注意到我在您的异常中遗漏了一个重要的一点:它说Timeout expired,而如果是连接超时,它应该说Connection timeout expired。虽然我目前不记得哪个框架版本确实在错误消息中添加了这种区别。您至少在 .NET 4.5 上吗?如果是这样,我敢肯定,如果它是一个,它会说连接超时。因此,您面临的问题可能是执行缓慢的查询。我更新了答案。
  • 感谢您的更新。如果问题仍然存在,我会尝试分析器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多