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

时间:2009-06-19 09:06:40

标签: nhibernate activerecord nhprof

这是一个常见的问题,但到目前为止所发现的解释和观察到的行为是分开的。

我们在MVC网站上想要以下nHibernate策略:

  • 请求的SessionScope(跟踪更改)
  • ActiveRecord.TransactonScope仅包装我们的插入(以启用批量回滚/提交)
  • 选择在交易之外(以减少锁定程度)
  • 延迟刷新插入(以便我们的插入/更新在会话结束时以UoW形式出现)

现在我们:

  • 不要从SessionScope获取隐含交易(使用FlushAction Auto或从不)
  • 如果我们使用ActiveRecord.TransactionScope,则没有延迟刷新,并且任何包含的选择也会在长时间运行的事务中被捕获。

我想知道是不是因为我们有一个旧版本的nHibernate(它来自非常接近2.0的主干)。

我们无法获得预期的nHibernate行为,并且性能很糟糕(使用NHProf和SqlProfiler监视数据库锁)。

1 个答案:

答案 0 :(得分:1)

以下是我们尝试过的事情:

  • 编写我们自己的TransactionScope(继承自ITransactionScope):
    • 提交上打开ActiveRecord.TransactionScope,而不是ctor(在需要之前延迟交易)
    • ctor中打开'SessionScope'(如果没有)(作为警卫)
  • 将我们的ID从身份转换为Guid
    • 这会停止在事务之外自动刷新insert / update(!)

现在我们有以下应用程序行为:

  • 来自MVC的请求
      服务所需的
    • SELECT在事务之外被解雇
    • 在我们的控制器中调用Repository.Add之前,
    • scope.Commit调用不会访问数据库
    • 所有INSERT s / UPDATE都作为原子单元包含在事务中,没有包含SELECT

...但由于某些原因nHProf现在!= sqlProfiler(select似乎在nHProf报告之前在db中发生)。

注意 在我受到抨击之前,我意识到这里的问题,并且知道SELECT不在事务中。这就是设计。我们的一些操作将在序列化事务中包含SELECT(我们现在有几个我们自己的TransactionScope实现)。我们的绝大多数代码都不需要最新的实时数据,而且我们还为各个运营商提供了序列化的工作负载。

同时 如果有人知道如何获得一个标识列(非PK)刷新后的帖子insert而无需手动刷新实体,特别是通过使用ActiveRecord标记(我认为在nHibernate映射文件中可能使用'生成'属性)告诉我!!