NHibernate、ActiveRecord、事务数据库锁以及提交何时刷新
这是一个常见的问题,但迄今为止发现的解释与观察到的行为存在一定的差距。
我们希望在我们的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以下是我们自此以来所做的尝试:
ctor
中打开ActiveRecord.TransactionScope
(延迟事务直到需要时)ctor
中打开“SessionScope”insert
/update
的自动刷新 (!)现在我们有以下应用程序行为:
SELECT
被触发,全部在事务之外Repository.Add
调用不会访问数据库,直到在我们的控制器中调用scope.Commit
INSERT
/UPDATE
都作为原子单元包装在事务内,不包含SELECT
。...但由于某种原因,nHProf 现在 != sqlProfiler (
select
s 似乎在 nHProf 报告之前就发生在数据库中)。注意
在我受到批评之前,我意识到这里的问题,并且知道 SELECT 不在事务中。 这就是设计。 我们的一些操作将包含序列化事务中的 SELECT(我们现在有几个自己的
TransactionScope
实现)。 我们的绝大多数代码不需要最新的实时数据,并且我们已经与各个操作员一起序列化了工作负载。还有
如果有人知道如何在插入后刷新身份列(非 PK),而无需手动刷新实体,特别是通过使用 ActiveRecord 标记(我认为在 nHibernate 映射文件中这是可能的)使用“生成”属性)请让我知道!
Here's what we have tried since:
ActiveRecord.TransactionScope
on the Commit, not in thector
(delays transaction until needed)ctor
if none are available (as a guard)insert
/update
outside of the Transaction (!)Now we have the following application behaviour:
SELECT
s needed by services are fired, all outside a transactionRepository.Add
calls do not hit the db untilscope.Commit
is called in our ControllersINSERT
s /UPDATE
s occur wrapped inside a transaction as an atomic unit, with noSELECT
s contained.... But for some reason nHProf now != sqlProfiler (
select
s 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!!