3

为了获得对缓慢或潜在缓慢区域的早期警告,我想要一个 NHibernate 拦截器,它可以充当性能监视器,以便任何花费超过给定时间的数据库操作都会引发一个事件并且(重要的是)应用程序日志的完整堆栈跟踪。

拦截器似乎是一个很好的窗口。但是,经过试验,似乎无论如何都无法捕捉到“刚刚从 SQL 中返回”的事件:

  • OnPreFlushOnPostFlush处理涉及写入但不在读取事件上调用的完整批次。
  • OnPrepareStatement()似乎是最好的开始测量,但停止?
  • 对于读取事件,OnLoad可能是停止时钟的地方,但它被称为每个实体返回一次 - 我怎么知道我何时到达所有实体的末尾?
  • 对于写入事件,我看不到任何 post-SQL 事件(除了那些在整个批次上工作的事件 -OnPostFlush并且OnAfterTransaction; 我得到的印象OnSave,OnFlushDirty等在实际数据库调用发生之前被调用 - 不过很高兴得到纠正)。

据我所知,文档严重缺乏关于 NHibernate 与数据库交互的管道顺序的确切信息,因此当在该管道中调用与实际 SQL 执行本身相关的不同事件和拦截器调用时。

这是需要永久可用的东西,位于后台,几乎不需要人工干预,除非检测到慢查询。它还需要在大型服务器场上无头运行,因此 NHibernate Profiler 等交互式工具已经过时:它实际上是我们可以启用和忘记的东西,让它在适当的时候记录。

有什么我错过或误解的吗?

4

1 回答 1

3

我有一个类似的问题。我想要测量并记录通过 NHibernate 的所有查询。我所做的是我编写了一个自定义批处理工厂(在这种情况下我使用 oracle)但是您可以将相同的技术应用于任何数据库:

1-)实施批处理工厂,(在这种情况下,我正在扩展现有工厂)

public class OracleLoggingBatchingBatcherFactory : OracleDataClientBatchingBatcherFactory
{
    public override IBatcher CreateBatcher(ConnectionManager connectionManager, IInterceptor interceptor)
    {
        return new OracleLoggingBatchingBatcher(connectionManager, interceptor);
    }
}

2-) 实现批处理器本身(在这种情况下,我正在扩展现有的批处理器)。确保您再次继承 IBatcher,因为我们希望调用我们的新方法

public class OracleLoggingBatchingBatcher : OracleDataClientBatchingBatcher, IBatcher
{
      .... // here override ExecuteNonQuery, DoExecuteBatch and ExecuteReader. 
           //You can do all kind of intercepting, logging or measuring here
           //If they are not overrideable just implement them and use "new" keyword if necessary
           //since we inherit IBatcher explicitly it will work polymorphically.
           //Make sure you call base implementation too or re-implement the method from scratch
}

3-) 通过 NHibernate 配置注册工厂:

    <property name="adonet.factory_class">OracleLoggingBatchingBatcherFactory, MyAssembly</property>
于 2014-03-11T10:30:58.910 回答