代码之家  ›  专栏  ›  技术社区  ›  Eoin Campbell

NHibernate.Exceptions.GenericADOException代码超时,但数据库超时

  •  2
  • Eoin Campbell  · 技术社区  · 13 年前

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

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

    从代码中,我一直在Selectcount(*)语句中得到一个异常。

    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窗口中,然后运行它,它将在<1秒。

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

    2 回复  |  直到 13 年前
        1
  •  2
  •   Radim Köhler user2134822    13 年前

    每当我遇到这个错误时,原因是 锁定 ( 从不 性能)。有两次会议(偶然)开幕。两人都启动了事务,其中一人锁定了表。

    问题可能是一些未处理的会话,或者“意外”的单例。。。举行公开会议。

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

    BTW:正如Oskar Berggren从你那里发现的那样,30秒的超时将与 <property name="command_timeout">30</property> 我相信,如果你能提供60120。。。因为锁的原因,这是不够的

        2
  •  1
  •   Community Mohan Dere    9 年前

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

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

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

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

    首先,我建议:

    • 您可以依靠投影(比如主表id),因为它比count(*)稍微有效一些,允许DB在可能的情况下只处理索引
    • 检查是否没有遗漏查询所需的任何索引
    • 你检查一下所有的表格统计数据是否是最新的

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