【发布时间】:2017-10-03 06:37:08
【问题描述】:
我们正在使用带有 Nhibernate 的 Castle Windsor,但遇到了命令超时问题。基本上这应该是一个直接解决的问题,但不知何故 Nhibernate 忽略了配置文件中的属性。
这是 Nhibernate 配置:
<factory id="nhibernate.factory">
<settings>
<item key="hibernate.command_timeout">3000</item>
<item key="hibernate.show_sql">false</item>
<item key="hibernate.connection.provider">NHibernate.Connection.DriverConnectionProvider</item>
<item key="hibernate.connection.driver_class">NHibernate.Driver.SqlClientDriver</item>
<item key="hibernate.connection.connection_string">#{coreDevConnectionString}</item>
<item key="hibernate.dialect">NHibernate.Dialect.MsSql2000Dialect</item>
<!--<item key="hibernate.cache.use_query_cache">true</item>-->
</settings>
<assemblies>
<assembly>Midas.Persistence</assembly>
<assembly>Midas.DbiCore</assembly>
</assemblies
超时时间仅为 30 秒。这是一个使用的代码示例:
Dim session As ISession = sessionManager.OpenSession()
Dim result As T
result = CType(session.Load(GetType(T), id), T)
session.Close()
setDirty(Of T)(result, False)
Return (result)
我尝试设置属性“hibernate.command_timeout”和“command_timeout”,但似乎都没有工作。
我收到一个 Nhibernate.AdoException,其中包含以下错误消息:
超时。在操作完成之前超时时间已过或服务器没有响应。
这里是 StackTrace:
System.Data.SqlClient.SqlException:超时已过期。在操作完成之前超时时间已过或服务器没有响应。在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔 breakConnection) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) 在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream , BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) 在 System.Data Midas.Persi 的 .SqlClient.SqlCommand.ExecuteNonQuery() stence.ScoreInformationMapper.Calculate(Int64 companyID, Int64 ModelID, Boolean ForceRecalculate, String& errorMessage, User user, InformationSource informationSource) at Midas.BusinessLogic.ScoreInformationController.CalculateScore2017(Int32 companyId, Int32 modelId, Boolean ForceRecalculate, User user, InformationSource informationSource) at Midas .BusinessLogic.ScoreInformationController.ReCalculateScore(ScoreInformation scoreInformation, User user, InformationSource informationSource, Boolean ForceCalculation, Boolean useRaiseEvent) 在 Midas.BusinessLogic.ScoreInformationController.AnyInformationUpdated(Object modifiedInformation, CompanyId companyId, User user, InformationSource informationSource) 在 Midas.BusinessLogic.ScoreInformationController。 OwnershipInformationUpdated(Object sender, InstancePersistedEventArgs1 e) at System.EventHandler1.Invoke(Object sender, TEventArgs e) at Midas.BusinessLogic.OwnershipInformationController.Save(OwnershipInformation instance, User user, InformationSource in formationSource) 在 Midas.Import.RegtidEjerregisterImportController.ProcessRow(DataRow[] sourceRows, User user, InformationSource informationSource, IImportMessageBuilder importMessageBuilder) 在 Midas.Import.ImportManager.ExecuteImport(IRowImportController rowImportController, SourceDataProviderConfig sourceDataProviderConfig, String informationSourceShortName)
【问题讨论】:
-
是否服务器能够响应?您可以从 SSMS 连接到它吗? 30秒很多。 full 异常是什么,包括它的调用堆栈?您可以通过
Exception.ToString()获得此信息。这将显示这是否是由连接超时引起的(意味着您根本无法连接到服务器)。命令超时意味着查询非常昂贵。 ORM 查询的 30 秒方式太长了。 -
超时的原因是因为锁。堆栈跟踪清楚地表明超时而不是连接超时。
-
张贴在这里,不要大声朗读。无论如何,如果问题是锁定,您应该修复您的查询,而不是用更大的超时来掩盖它。 为什么很慢?执行计划是什么?实际查询是什么?有没有缺失的索引?使用适当的索引,您可以获得 300 倍(不是 300%,300%)倍的性能
-
如果查询很好但处理了大量数据,则说明您完全使用了错误的工具。 所有 ORM,而不仅仅是 NH,都不适合报告查询。没有要返回和映射到行为的实体,只有 DTO。他们生成的查询在这种情况下不会表现良好。当您拥有大量数据时,您希望将其流式传输,而不是一口气全部吃完。
-
我已经添加了 StackTrace。我会看看索引。
标签: nhibernate ado.net castle-windsor