【问题标题】:NHibernate.Exceptions.GenericADOException Timeout from code but not from DBNHibernate.Exceptions.GenericADOException 来自代码但不是来自数据库的超时
【发布时间】:2013-08-25 02:11:26
【问题描述】:

我有一个 NHibernate 查询(正在填充 EXTJS 网格)

它向数据库发出 2 个查询,一个用于获取记录计数(用于分页目的),另一个用于获取前 N 行以填充网格。

从代码中,我一直在 Select count(*) 语句中遇到异常。

NHibernate.Exceptions.GenericADOException: 
Failed to execute multi criteria[SQL: 
 SELECT count(*) as y0_ FROM RecordView this_ inner join ProcessesView 
 process1_ on this_.ProcessId=process1_.Id inner join BusinessModelsView 
 businessmo3_ on process1_.BusinessModelId=businessmo3_.Id inner join BatchesView
 batch2_ on this_.BatchId=batch2_.Id WHERE this_.ProcessId = ?;
] ---> System.Data.SqlClient.SqlException: Timeout expired.  
The timeout period elapsed prior to completion of the operation or the server 
is not responding.

但是,如果我将确切的查询放入 SSMS 窗口并运行它,它会在

NHibernate 在这里做了什么“有趣”的事情。是否存在执行计划/缓存问题。我完全不知道为什么会发生这种情况。

【问题讨论】:

  • 超时需要多长时间?
  • 30 秒。我们的配置连接字符串中的 Sql 超时值

标签: sql-server nhibernate timeout


【解决方案1】:

每当我遇到此错误时,原因是锁定从不性能)。有两个会话打开(意外)。两个都启动了事务,其中一个锁定了表。

问题可能是一些未处理的会话,或“意外”单例...持有已打开的会话。

这个答案并不像我希望的那样直截了当,但我对方向很有把握。因为我经历过同样的(并且是有罪的)

顺便说一句:正如 Oskar Berggren 从你那里发现的那样,30 秒超时将与 <property name="command_timeout">30</property> 有关。我敢肯定,如果你提供 60、120 ......由于锁定,这还不够

【讨论】:

    【解决方案2】:

    SQL SERVER 处理您的两个查询的方式不同

    • 您的 NH 查询已在第一次执行时根据表统计信息和参数的第一个值进行编译。生成的查询计划将用于所有后续调用,而不考虑参数值

    • 您的 SQL 查询(我猜,您将 ? 替换为实际值)根据统计数据和值对每个值进行不同的编译。

    您的第一次 NH 编译可能已经生成了一个查询计划,对第一个值有效,但在一般情况下不是。

    首先,我建议:

    • 您可以依靠投影(比如在主表 id 上),因为它比 count(*) 稍微有效一些,允许数据库在可能的情况下仅在索引上工作
    • 您检查您没有错过任何查询所需的索引
    • 您检查所有表统计信息是否都是最新的

    如果这不能缩短执行时间,这篇文章提供了一些选项(重新编译可能是一个不错的选择): Query executed from Nhibernate is slow, but from ADO.NET is fast

    【讨论】:

      猜你喜欢
      • 2019-07-23
      • 1970-01-01
      • 2018-04-11
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 2021-09-29
      • 2019-10-22
      • 1970-01-01
      相关资源
      最近更新 更多