ASP Mvc Nhibernate 问题
我在 MVC Web 应用程序中遇到了 Nhibernate 的一些奇怪问题。
没有 1 个一致的错误,我不断收到大量随机错误:
- 事务未成功启动
- 不允许启动新请求,因为它应该带有有效的事务描述符
- 意外的行计数:-1;预期:1
为了给设置提供一些背景信息,我使用 Ninject 来 DI 会话和其他 Nhibernate 相关对象,目前我正在使用 RequestScope,但我尝试过 SingletonScope。我有一个庞大而复杂的数据模型,它作为一个整体读出,但保留在单独的部分中,因为这些都可以单独编辑和保存。
一个例子是有一个 Customer 对象,它包含一个地址对象、一个联系人对象、朋友对象、以前的订单对象等等...
所以整个对象被读出,然后映射到 UI 域模型,然后以不同的方式显示页面内的部分内容。每个部分都可以通过 ajax 单独更新,因此您可以更新 1 个部分,也可以一起更新它们。当我尝试将它们全部保存在一起时,这似乎主要给我带来了问题(因此 2-4 个同时的 ajax 请求来保存模型的块)。
现在我的集成测试运行良好,它只是测试实体的持久性和检索。整体而言,单独而言,一切都很好,但是在 Web 应用程序中,它们似乎只是不断抛出随机异常,并且最初拒绝在 Nhibernate 缓存之外保留。我找到了解决这个问题的方法,将大多数工作单元包装在事务中,这使数据得以保留,但开始向混合中添加新的错误。
最初我想从项目中废弃 Nhibernate,因为虽然我真的想要它的持久/缓存层,但它对于我的领域来说似乎不够灵活,这看起来很奇怪,因为我以前使用过它没有太多问题,尽管它不喜欢 1-1 映射。
那么有没有其他人在 ASP MVC 应用程序中遇到过这样的不稳定事务/nhibernate 问题...我知道这可能有点含糊,因为错误并不指向一件事,而且它并不总是错误,所以它就像刺入黑暗,但我没有主意,所以任何帮助都会很棒!
-- 更新 --
我无法发布所有相关代码,因为该项目很大,但事务位看起来像:
using (var transaction = sessionManager.Session.BeginTransaction(IsolationLevel.ReadUncommitted))
{
try
{
// Do unit of work
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
}
我在这个项目上遇到的一些主要问题源于:
- 与组合键存在一些 1-1 关系,但从逻辑上讲,这是有道理的
- Nhibernate 域实体通过映射层成为 UI 域实体,然后在保存时反之亦然。这里的问题是,使用 1-1 映射时,在保留示例地址时,我必须创建一个具有正确 ID 的代理客户对象,然后合并。
- 有很多 Ajax 处理整个模型的块(我说的是只有一个模型,但有很多顶级模型,只有一个是最重要的)
I am experiencing some bizarre problems with Nhibernate within my MVC web application.
There is not 1 consistent error, I keep getting loads of random ones:
- Transaction not successfully started
- New request is not allowed to start because it should come with valid transaction descriptor
- Unexpected row count: -1; expected: 1
To give a little context to the setup, I am using Ninject to DI the sessions and other Nhibernate related objects, currently I am using RequestScope however I have tried SingletonScope. I have a large and complicated data model, which is read out as a whole, but persisted back in separate parts, as these can all be edited and saved individually.
An example would be having a Customer object, which contains a address object, a contact object, friends object, previous orders object etc etc...
So the whole object is read out, then mapped to the UI domain models and then displayed in different partials within the page. Each partial can be updated individually via ajax, so you may update 1 section or you could update them all together. It seems mainly to give me the problems when I try to persist them all together (so 2-4 simultanious ajax requests to persist chunks of the model).
Now I have integration tests that work fine, which just test the persistence and retrieval of entities. As a whole and individually and all pass fine, however in the web app they just seem to keep throwing random exceptions, and originally refused to persist outside of the Nhibernate cache. I found a way round this by wrapping most units of work within transactions, which got the data persisting but started adding new errors to the mix.
Originally I was thinking of just scrapping Nhibernate from the project, as although I really want its persistance/caching layer, it just didnt seem to be flexible enough for my domain, which seems odd as I have used it before without much problem, although it doesn't like 1-1 mappings.
So has anyone else had flakey transaction/nhibernate issues like this within an ASP MVC app... I know this may be a bit vague as the errors dont point to one thing, and it doesn't always error, so its like stabbing in the dark, but I am out of ideas so any help would be great!
-- Update --
I cannot post all relevant code as the project is huge, but the transaction bit looks like:
using (var transaction = sessionManager.Session.BeginTransaction(IsolationLevel.ReadUncommitted))
{
try
{
// Do unit of work
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
}
Some of the main problems I have had on this project have stemmed from:
- There are some 1-1 relationships with composite keys, but logically it makes sense
- The Nhibernate domain entities go through a mapping layer to become the UI domain entities, then vice versa when saving. Problem here is that with the 1-1 mappings, when persisting the example Address I have to make a Surrogate Customer object with the correct Id then merge.
- There is ALOT of Ajax that deals with chunks of the overall model (I talk like there is one single model, but there are quite a few top level models, just one that is most important)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一些可能有帮助的注释。我使用温莎,但想象概念是相同的。听起来可能是多种因素的结合。
SessionFactory 应创建为单例,并且会话应针对每个 Web 请求。像这样的东西:
小心保持事务打开时间过长,尽可能缩短它们的生命周期,以避免死锁。
小心保持
Some notes that may help. I use windsor but imagine the concepts are the same. Sounds like there may be a combination of things.
SessionFactory should be created as singleton and session should be per web request. Something like:
Be careful of keeping transactions open for too long, keep them as short lived as possible to avoid deadlocks.