title: Determine if NHibernate Session is in an error state
body: <p>All,</p>
  
  <p>Is it possible to determine from the session object (ISession, or its ISessionImplementor) if an error occured? Or, is it possible to hook up an even handler that is invoked when an error occurs on a session?</p>
  
  <p>I am well aware of the pattern for dealing w/ sessions by wrapping your code in try/catch and disposing the session immediately. In my case though, I have implemented something equivalent to session scope that hands out hibernate session to my DAOs that run in the current scope. When I give out the hibernate session, the client code uses it simply to run a persistent operation and I don't want the client to be responsible for doing session clean-up,- that is the responsibility of the session scope. Here's example:</p>
  
  <pre><code>using (new SessionScope(SessionHelper.OpenSession()))
  {
      // do read/write etc.
      // ex:
      mydao.MakePersistent(someEntity);  // &lt;-- an error can occur here
  } // implicit flush/clean up, BUT in order to do this correctly I have to know if the session in the scope has no errors!
  </code></pre>
  
  <p>As you can see, the SessionScope implements IDisposable and there I do session finalization like flush, tx.Commit(), and disposal. But, I can't flush a session if an error occured on it!</p>
  
  <p>One work around is not to give out the raw hibernate session, but a wrapper object w/ methods for executing session operations, that way I can wrap any operation in try/catch and know when the error occured. If you ask me, that is silly workaround.</p>
  
  <p>The other option is that all DAOs inform my session scope that an error occured,- this means that all my DAO methods (in the catch block) must check if session scope is defined, and if it is, they are responsible for failing the session (scope.FailSession(session);) That's much better but I have to do it religiously in all my DAO and if I forget, my session scope will misbehave by calling session.Flush() on an errored session.</p>
  
  <p>Thanks to Oskar B. comment it is required to use a transaction based approach for any logic that needs to have ACID properties or is at risk of an exception that may not relate to persistence. Here's revised solution:</p>
  
  <pre><code>using (var txScope = new TransactionScope(SessionHelper.OpenSession()))
  {
       Customer cust = mydao.getCustomer();
       Order order = mydao.getOrder(cust);
       // modify order, etc. (an error may occur at any time within this scope)
       txScope.VoteCommit();           
  } // if we voted commit, it will flush/commit otherwise it will rollback 
  </code></pre>