每个请求的NHibernate会话/事务阻止多次插入

时间:2012-07-19 17:46:35

标签: c# asp.net-mvc-3 nhibernate transactions session-per-request

我正在处理的MVC 3项目提交/回滚我在当前会话结束时进行的任何插入/更新调用。这在大多数情况下都可以正常工作,除了现在我正在进行多次插入。

当csv上传到站点时,每个记录都会被解析并插入到数据库中。问题是,如果一个记录无法插入,所有先前的记录都会回滚,所有后续尝试都会失败并显示错误:

    don't flush the Session after an exception occurs

如何禁用每会话请求(或者我必须以某种方式“重新启动”事务)?

编辑:详情

每个请求的会话内容在实现IHttpModule的类中配置。该类采用HttpApplication上下文和UnitOfWork类。这是提交和回滚的地方。

上面提到的UnitOfWork使用StructureMap注入到存储库中。

就像我说的,这种行为适用于99%的网站其他部分,我只需要进行批量更新即可忽略会话每请求事务。或者我需要为每个新记录手动重新启动事务。我只是不知道如何。

2 个答案:

答案 0 :(得分:0)

ISession具有FlushMode属性,默认值为Auto

自动有时会在查询执行之前刷新ISession,以确保查询永远不会返回失效状态。这是默认的刷新模式。

提交调用Transaction.Commit()时刷新ISession

从不除非Flush()被显式调用,否则永远不会刷新ISession 应用。此模式对于只读事务非常有效

未指定未指定的刷新模式的特殊值。

始终在每次查询之前刷新ISession。这几乎总是不必要和低效的。

尝试在ISession's FlushMode值上更改Commit属性。

答案 1 :(得分:0)

  

每个请求的会话都是在实现IHttpModule的类中配置的。

你在HttpModule中启动的每个请求会话是做的事情,而不是NHibernate。如何禁用它,取决于您的代码。我个人不喜欢在一些UnitOfWork类中抽象NHibernate,因为现在你意识到你使用的抽象不够好,而且脏黑客可能是现在唯一的方法。

您实际想做的事情(不推荐)是:

foreach (var row in rows)
{
    using (var session = SessionFactory.OpenSession())
    using (var tx = session.BeginTransaction())
    {
         var whatever = ...
         session.Save(whatever);
         tx.Commit();
    }
}