NHibernate、ActiveRecord、事务数据库锁以及刷新提交时

NHibernate、ActiveRecord、事务数据库锁以及刷新提交时,nhibernate,activerecord,nhprof,Nhibernate,Activerecord,Nhprof,这是一个常见的问题,但迄今为止发现的解释与观察到的行为有一定距离 我们希望在MVC网站中采用以下nHibernate策略: 请求的会话范围(跟踪更改) 仅包装插入的ActiveRecord.TransactionScope(启用批处理的回滚/提交) 选择在事务外部(以减少锁的范围) 插入刷新延迟(因此我们的插入/更新在会话结束时作为UoW发生) 现在我们: 不从会话范围获取隐含事务(使用FlushaAction Auto或Never) 如果我们使用ActiveRecord.Transact

这是一个常见的问题,但迄今为止发现的解释与观察到的行为有一定距离

我们希望在MVC网站中采用以下nHibernate策略:

  • 请求的
    会话范围
    (跟踪更改)
  • 仅包装插入的
    ActiveRecord.TransactionScope
    (启用批处理的回滚/提交)
  • 选择在事务外部(以减少锁的范围)
  • 插入刷新延迟(因此我们的插入/更新在会话结束时作为UoW发生)
现在我们:

  • 不从
    会话范围
    获取隐含事务(使用FlushaAction Auto或Never)
  • 如果我们使用
    ActiveRecord.TransactionScope
    ,则不会延迟刷新,并且任何包含的选择也会在长时间运行的事务中被捕获
我想知道这是否是因为我们有一个旧版本的nHibernate(它来自trunk,非常接近2.0)


我们无法获得预期的nHibernate行为,性能很差(使用NHProf和SqlProfiler监视db锁)

以下是我们自那以后的尝试:

  • 编写了我们自己的TransactionScope(继承自ITransactionScope),其中:
    • 提交上打开一个
      ActiveRecord.TransactionScope
      ,而不是在
      ctor
      中(将事务延迟到需要时)
    • 如果没有可用的“会话范围”(作为保护),则在
      ctor
      中打开“会话范围”
  • 已将ID从标识转换为Guid
    • 这停止了事务(!)之外的
      插入
      /
      更新的自动刷新
现在我们有以下应用程序行为:

  • 来自MVC的请求
    • SELECT
      s触发服务所需的,所有这些都在事务之外
    • Repository.Add
      调用在控制器中调用
      scope.Commit
      之前不会命中数据库
    • 所有
      INSERT
      s/
      UPDATE
      s作为一个原子单元包装在事务中,不包含
      SELECT
      s
。。。但出于某种原因,nHProf现在sqlProfiler(
select
s似乎在nHProf报告之前发生在数据库中)

注意 在我被激怒之前,我意识到这里的问题,并且知道选择不在交易中。这就是设计。我们的一些操作将在序列化事务中包含选择(我们现在有两个自己的
TransactionScope
实现)。我们的绝大多数代码不需要最新的实时数据,并且我们与各个操作员一起序列化了工作负载

同时
如果有人知道如何在无需手动刷新实体的情况下,尤其是通过使用ActiveRecord标记(我认为在nHibernate映射文件中使用“生成的”属性)在post-
insert
后刷新标识列(非PK)请告诉我

我们还实现了对ActiveRecord的自定义添加,以允许指定NH属性“generateinserts”。