NHibernate session/transaction per request preventing multiple inserts

1.7k Views Asked by At

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.

2

There are 2 best solutions below

0
On

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();
    }
}
0
On

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.