2

这是一个常见的问题,但到目前为止发现的解释和观察到的行为有一定的差距。

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

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

现在我们:

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

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

我们只是无法获得预期的 nHibernate 行为,而且性能很差(使用 NHProf 和 SqlProfiler 来监控数据库锁)。

4

1 回答 1

1

这是我们从那以后尝试过的:

  • 编写我们自己的 TransactionScope(继承自 ITransactionScope):
    • ActiveRecord.TransactionScopeCommit上打开一个,而不是在ctor(延迟事务直到需要)
    • 在没有可用的情况下打开“SessionScope” ctor(作为警卫)
  • 将我们的 id 从身份转换为 Guid
    • 这停止了​​事务的insert/外部的自动刷新(!)update

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

  • 来自 MVC 的请求
    • SELECT服务所需的 s 被触发,全部在事务之外
    • Repository.Addscope.Commit在我们的控制器中调用之前,调用不会命中数据库
    • 所有INSERTs / UPDATEs 都作为原子单元包装在事务中,不SELECT包含任何 s。

...但是由于某种原因,现在 nHProf != sqlProfiler (selects 似乎在 nHProf 报告它之前发生在数据库中)。

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

另外,如果有人知道如何在insert无需手动刷新实体的情况下刷新身份列(非 PK),尤其是通过使用 ActiveRecord 标记(我认为在 nHibernate 映射文件中使用“生成”属性是可能的告诉我!!

于 2009-06-27T11:51:07.290 回答