NHibernate和拦截器 - 测量/监控SQL往返时间

时间:2014-03-11 09:32:20

标签: nhibernate iinterceptor

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

拦截器似乎是一个很好的窗口。但是,经过实验,似乎没有任何方法可以捕获“刚从SQL返回”事件:

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

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

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

我有什么遗漏或误解了吗?

1 个答案:

答案 0 :(得分:3)

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

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

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

2-)实现Batcher本身(在这种情况下,我正在扩展现有的batcher)。确保再次继承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 config注册工厂:

    <property name="adonet.factory_class">OracleLoggingBatchingBatcherFactory, MyAssembly</property>