0

The MVC 3 project I am working on commits/rolls back whatever insert/update calls I make at the end of the current session. This works fine in most cases except for now where I am doing multiple inserts.

When a csv is uploaded to the site, each record is parsed and inserted into the DB. The problem is, if one record fails to insert, all previous records get rolled back and all subsequent attempts fail with the error:

    don't flush the Session after an exception occurs

How can I disable the request-per-session (or do I have to "restart" the transaction somehow)?

EDIT: Details

The session per request stuff is configured in a class that implements IHttpModule. This class takes an HttpApplication context and UnitOfWork class. This is where the commits and rollbacks occur.

The UnitOfWork, mentioned above, is injected into the repositories using StructureMap.

Like I said, this behavior is fine for 99% of the rest of the site, I just need to get this bulk-update to ignore session-per-request transactions. Or I need to manually restart a transaction for each new record. I just don't know how.

getit
  • 623
  • 2
  • 8
  • 30
  • This behavior is not "automatic", somewhere you must be catching the exception and rolling back the session. Could you take a look at the Global.asax? – Andre Calil Jul 19 '12 at 17:50
  • I've added more details above. – getit Jul 19 '12 at 17:59
  • Are you able to retrieve the instance of the current session? If so, you can use it to create a new transaction and, `using` it, try to preform the update. Surround it with a try/catch so the exception won't get caught by the HttpModule and you're fine. – Andre Calil Jul 19 '12 at 18:03
  • If that exception is an `HibernateException` you should discard the ISession. Also, it seems a little odd that you'd want to allow a partial import of a csv...but if you really need to, I'd simply get a fresh ISession directly from the SessionFactory and avoid the request-scoped-session. – dotjoe Jul 19 '12 at 19:53
  • 1
    I'm voting to close this question as off-topic because it (1) was caused by a problem that can no longer be reproduced, (2) has no response from asker who was last active in 2014, (3) has no accepted nor useful answers. – aaron Dec 04 '17 at 14:22

2 Answers2

0

ISession has FlushMode property with default value Auto,

Auto The ISession is sometimes flushed before query execution in order to ensure that queries never return stale state. This is the default flush mode.

Commit The ISession is flushed when Transaction.Commit() is called

Never The ISession is never flushed unless Flush() is explicitly called by the application. This mode is very efficient for read only transactions

Unspecified Special value for unspecified flush mode.

Always The ISession is flushed before every query. This is almost always unnecessary and inefficient.

Try change ISession's FlushMode property on Commit value.

GSerjo
  • 4,725
  • 1
  • 36
  • 55
0

The session per request stuff is configured in a class that implements IHttpModule.

That session-per-request that you start in the HttpModule is something you do, not NHibernate. How to disable it, depends on your code. I personally don't like abstracting NHibernate in some UnitOfWork-class, because now you realize that the abstraction you used isn't good enough and a dirty hack is probably the only way to go now.

What you actually would like to do (and is not recommended) is:

foreach (var row in rows)
{
    using (var session = SessionFactory.OpenSession())
    using (var tx = session.BeginTransaction())
    {
         var whatever = ...
         session.Save(whatever);
         tx.Commit();
    }
}
Jeroen
  • 979
  • 1
  • 7
  • 16