【问题标题】:NHibernate, ActiveRecord, Transaction database locks and when Commits are flushedNHibernate、ActiveRecord、事务数据库锁以及何时刷新提交
【发布时间】:2009-06-19 09:06:39
【问题描述】:

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

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

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

现在我们:

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

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

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

【问题讨论】:

    标签: nhibernate activerecord nhprof


    【解决方案1】:

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

    • 编写了我们自己的 TransactionScope(继承自 ITransactionScope):
      • Commit 中打开 ActiveRecord.TransactionScope,而不是在 ctor 中(延迟事务直到需要)
      • 如果没有可用的,则在ctor 中打开一个“SessionScope”(作为保护)
    • 将我们的 ID 从身份转换为 Guid
      • 这停止了在事务之外自动刷新 insert/update (!)

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

    • 来自 MVC 的请求
      • 服务所需的SELECTs 在事务之外被触发
      • Repository.Add 在控制器中调用 scope.Commit 之前不会访问数据库
      • 所有INSERTs / UPDATEs 都以原子单元的形式包装在事务中,不包含SELECTs。

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

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

    如果有人知道如何在insert 之后刷新身份列(非 PK)而不需要手动刷新实体,特别是通过使用 ActiveRecord 标记(我认为在 nHibernate 映射文件中使用“生成”是可能的)属性)告诉我!!

    【讨论】:

    • 我们还实现了对 ActiveRecord 的自定义添加,以允许指定 NH 属性“generateinserts”。
    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    相关资源
    最近更新 更多