NHibernate、ActiveRecord、事务数据库锁以及刷新提交时
这是一个常见的问题,但迄今为止发现的解释与观察到的行为有一定距离 我们希望在MVC网站中采用以下nHibernate策略:NHibernate、ActiveRecord、事务数据库锁以及刷新提交时,nhibernate,activerecord,nhprof,Nhibernate,Activerecord,Nhprof,这是一个常见的问题,但迄今为止发现的解释与观察到的行为有一定距离 我们希望在MVC网站中采用以下nHibernate策略: 请求的会话范围(跟踪更改) 仅包装插入的ActiveRecord.TransactionScope(启用批处理的回滚/提交) 选择在事务外部(以减少锁的范围) 插入刷新延迟(因此我们的插入/更新在会话结束时作为UoW发生) 现在我们: 不从会话范围获取隐含事务(使用FlushaAction Auto或Never) 如果我们使用ActiveRecord.Transact
- 请求的
(跟踪更改)会话范围
- 仅包装插入的
(启用批处理的回滚/提交)ActiveRecord.TransactionScope
- 选择在事务外部(以减少锁的范围)
- 插入刷新延迟(因此我们的插入/更新在会话结束时作为UoW发生)
- 不从
获取隐含事务(使用FlushaAction Auto或Never)会话范围
- 如果我们使用
,则不会延迟刷新,并且任何包含的选择也会在长时间运行的事务中被捕获ActiveRecord.TransactionScope
我们无法获得预期的nHibernate行为,性能很差(使用NHProf和SqlProfiler监视db锁) 以下是我们自那以后的尝试:
- 编写了我们自己的TransactionScope(继承自ITransactionScope),其中:
- 在提交上打开一个
,而不是在ActiveRecord.TransactionScope
中(将事务延迟到需要时)ctor
- 如果没有可用的“会话范围”(作为保护),则在
中打开“会话范围”ctor
- 在提交上打开一个
- 已将ID从标识转换为Guid
- 这停止了事务(!)之外的
/插入
更新的自动刷新
- 这停止了事务(!)之外的
- 来自MVC的请求
s触发服务所需的,所有这些都在事务之外SELECT
调用在控制器中调用Repository.Add
之前不会命中数据库scope.Commit
- 所有
s/INSERT
s作为一个原子单元包装在事务中,不包含UPDATE
sSELECT
select
s似乎在nHProf报告之前发生在数据库中)
注意
在我被激怒之前,我意识到这里的问题,并且知道选择不在交易中。这就是设计。我们的一些操作将在序列化事务中包含选择(我们现在有两个自己的TransactionScope
实现)。我们的绝大多数代码不需要最新的实时数据,并且我们与各个操作员一起序列化了工作负载
同时
如果有人知道如何在无需手动刷新实体的情况下,尤其是通过使用ActiveRecord标记(我认为在nHibernate映射文件中使用“生成的”属性)在post-
insert
后刷新标识列(非PK)请告诉我 我们还实现了对ActiveRecord的自定义添加,以允许指定NH属性“generateinserts”。