NHibernate - “GenericADOException:无法执行查询”

Posted

技术标签:

【中文标题】NHibernate - “GenericADOException:无法执行查询”【英文标题】:NHibernate - "GenericADOException: could not execute query" 【发布时间】:2016-09-08 13:22:46 【问题描述】:

我们使用 NHibernate v3.1.0.4000 的生产环境突然在使用全文搜索进行搜索时开始出现此错误:

[SqlException (0x80131904): 超时。在操作完成之前超时时间已过或服务器没有响应。] System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔 breakConnection)+404 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +412 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1363 System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +59 System.Data.SqlClient.SqlDataReader.get_MetaData() +118 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +6388257 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔返回流,布尔异步)+6389826 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +538 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String 方法) +28 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法)+256 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior 行为)+19 System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader() +23 NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd) +845 NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session) +580 NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +275 NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +205 NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +195

[GenericADOException: 无法执行查询 [ SELECT count(distinct this_.IdDocument) as y0_ FROM Document.Document this_ inner join Document.DocumentCopy documentc1_ on this_.IdDocument=documentc1_.IdDocument WHERE ((@p0 = @p1 and contains(this_.Title, @p2)) 和this_.IsDeleted = @p3) and (((@p4 = @p5 and documentc1_.CreationDate >= @p6) and documentc1_.CreationDate 0 #1>0 #2>"ýÿýÿýÿýÿýÿýÿÿýÿ*" #3>False #4>0 #5>0 #6>12/5/2015 12:00:00 ýÿýÿ #7>12/5 /2016 11:59:00 东东 #8>1 #9>1 [SQL: SELECT count(distinct this_.IdDocument) as y0_ FROM Document.Document this_ inner join Document.DocumentCopy documentc1_ on this_.IdDocument=documentc1_.IdDocument WHERE ((@p0 = @p1 and contains(this_.Title, @p2) ) and this_.IsDeleted = @p3) and (((@p4 = @p5 and documentc1_.CreationDate >= @p6) and documentc1_.CreationDate 1 criteria, Int32& count, Dictionary2 openFieldCriteria) +272 ServicesImplementation.DocumentService.GetDocuments(Criteria1 criteria, Int32& count, String metadataSearchTerm) +510 Docman.Models.List.ListModel.GetDocuments(Int32& count) +102 ASP._Page_Views_List_Index_cshtml.Execute() in d:\wwwroot\inetpub\docman\Views\List\Index.cshtml:27 System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +280 System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +104 System.Web.WebPages.StartPage.ExecutePageHierarchy() +143 System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +157 System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +384 System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +33 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func1 续) +826372 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 过滤器, ActionResult actionResult) +265 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +827248 System.Web.Mvc.Controller.ExecuteCore() +159 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +335 System.Web.Mvc.c__DisplayClassb.b__5() +62 System.Web.Mvc.Async.c__DisplayClass1.b__0() +20 System.Web.Mvc.c__DisplayClasse.b__d() +54 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375

我已经在 SSMS 上尝试了上面列出的查询,它似乎运行良好且快速。

这里提到了一个类似的错误:Nhibernate FieldNameLookup throws IndexOutOfRangeException,尽管我的错误消息中不包含任何IndexOutOfRangeException

谁能告诉我这可能是什么原因?

更新:

更多信息:

我们正在使用预测。

根据错误日志,错误源于一些只返回一个计数而不是许多行的查询。

正如我之前所说,当我从 SSMS 运行时,相同的查询(在错误日志中列出)运行速度很快并且没有任何问题。然而,执行此 SQL 查询的应用程序发出的所有查询似乎都因上述错误而失败。

由于我们为 NH 使用了自定义包装器,因此您可能不清楚代码。

我认为我在异常顺序上是错误的,首先发生超时,然后 ADO.net 报告另一个错误。 所以,我想这毕竟是一个超时......

更新 2:

经过一些额外的研究,这似乎与这个问题有关,并且查询确实超时了,只是不是来自 SSMS:

Query times out when executed from web, but super-fast when executed from SSMS

【问题讨论】:

数据说是超时问题。 您要带回多少数据?这样做的代码是什么样的?你在使用投影吗? @Najera 如果您在第一个异常下方查看,还有另一个异常似乎是内部异常。 @Najera 但也许你是对的:首先它必须是 SQL 异常,然后是 ADO 异常。 :^) 我希望人们只是在他们的异常日志中写了Inner exception :\r\n。这会让事情变得更加明显...... @Fran 我添加了更多细节。我现在在想,这可能确实是一个超时问题。我对这两个例外的顺序有点困惑...... 【参考方案1】:

结果是无法从 SSMS 复制的超时,因为它使用了不同的 ARITHABORT 值(在我的应用会话和 SSMS 会话之间)。

一旦我将 DB 的默认值设置为 ON/1,一切都已修复:

USE [master];
GO
ALTER DATABASE [database_name] SET ARITHABORT ON WITH NO_WAIT;
GO

请看这里:https://dba.stackexchange.com/a/95090/71232

【讨论】:

错了,大错特错。您刚刚从使用过的查询计划缓存中临时驱逐了一个错误的查询计划。一段时间后麻烦会回来并再次咬你。你找到this answer 的事实很有希望,但看起来你读得太快了。您的实际问题很可能是索引问题,导致 SQL Server 有时会生成错误的查询计划并将其放入缓存中。 @Frédéric 但是,MS 建议无论如何都要将此设置设为 ON (msdn.microsoft.com/en-us/library/ms190306.aspx)。所以,我不认为做我所做的事情是一件坏事。此外,该查询在其中包含一个全文搜索查询,并且大多数全文索引在数据库中超过 70% 是碎片化的(当您运行没有 DBA 的系统时会发生这种情况......)。没有全文搜索部分的相同查询运行得很快,所以我猜 F.T.S.是什么造成了差异。我们的非全文搜索索引可能需要调整,但我认为这不是原因。 :) 拥有它到on 并不是一件坏事,当然,但相信它实际上完全解决了您遇到的麻烦可能是一件坏事。见here。在我遇到的所有情况下,实际问题始终是索引问题,而不仅仅是 ARITHABORT 设置。 @Frédéric OK。我知道了。我也会尝试检查索引。 :)

以上是关于NHibernate - “GenericADOException:无法执行查询”的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate教程(19) —— 一级缓存

Nhibernate学习教程-- 开篇有益

NHibernate 2 + NHibernate.JetDriver + MS Access:如何访问表的“附件”字段

NHibernate3剖析:Query篇之NHibernate.Linq增强查询

ASP.NET MVC、NHibernate 会话和 NHibernate 事件

NHibernate 2 + Fluent Nhibernate 中等信任