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

发布于 2024-07-25 19:04:21 字数 612 浏览 6 评论 0原文

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

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

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

现在,目前我们:

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

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

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

This is a common question, but the explanations found so far and observed behaviour are some way apart.

We have want the following nHibernate strategy in our MVC website:

  • A SessionScope for the request (to track changes)
  • An ActiveRecord.TransactonScope to wrap our inserts only (to enable rollback/commit of batch)
  • Selects to be outside a Transaction (to reduce extent of locks)
  • Delayed Flush of inserts (so that our insert/updates occur as a UoW at end of session)

Now currently we:

  • Don't get the implied transaction from the SessionScope (with FlushAction Auto or Never)
  • If we use ActiveRecord.TransactionScope there is no delayed flush and any contained selects are also caught up in a long-running transaction.

I'm wondering if it's because we have an old version of nHibernate (it was from trunk very near 2.0).

We just can't get the expected nHibernate behaviour, and performance sucks (using NHProf and SqlProfiler to monitor db locks).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

童话里做英雄 2024-08-01 19:04:21

以下是我们自此以来所做的尝试:

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

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

  • 来自 MVC 的请求
    • 服务所需的SELECT被触发,全部在事务之外
    • Repository.Add 调用不会访问数据库,直到在我们的控制器中调用 scope.Commit
    • 所有 INSERT / UPDATE 都作为原子单元包装在事务内,不包含 SELECT

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

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

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

Here's what we have tried since:

  • Written our own TransactionScope (inherits from ITransactionScope) that:
    • Opens a ActiveRecord.TransactionScope on the Commit, not in the ctor (delays transaction until needed)
    • Opens a 'SessionScope' in the ctor if none are available (as a guard)
  • Converted our ids to Guid from identity
    • This stopped the auto flush of insert/update outside of the Transaction (!)

Now we have the following application behaviour:

  • Request from MVC
    • SELECTs needed by services are fired, all outside a transaction
    • Repository.Add calls do not hit the db until scope.Commit is called in our Controllers
    • All INSERTs / UPDATEs occur wrapped inside a transaction as an atomic unit, with no SELECTs contained.

... But for some reason nHProf now != sqlProfiler (selects seems to happen in the db before nHProf reports it).

NOTE
Before I get flamed I realise the issues here, and know that the SELECTs aren't in the Transaction. That's the design. Some of our operations will contain the SELECTs (we now have a couple of our own TransactionScope implementations) in serialised transactions. The vast majority of our code does not need up-to-the-minute live data, and we have serialised workloads with individual operators.

ALSO
If anyone knows how to get an identity column (non-PK) refreshed post-insert without a need to manually refresh the entity, and in particular by using ActiveRecord markup (I think it's possible in nHibernate mapping files using a 'generated' attribute) please let me know!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文