title: When to commit NHibernate Transaction?
body: <p>While very familiar to Webforms and Linq, I am a novice to the ASP.NET MVC and NHibernate World.  I have been working through a project using Bob Cravens' <a href="http://blog.bobcravens.com/2010/07/using-nhibernate-in-asp-net-mvc/" rel="nofollow">examples</a>.  My application is mostly reads and non-sequential writes, so typically I would not use a transactions. But to implement the Unit-of-Work pattern, all my research including <a href="http://ayende.com/blog/3775/nh-prof-alerts-use-of-implicit-transactions-is-discouraged" rel="nofollow">Ayende's blog</a> says I should.</p>
  
  <p>The problem I have is this -</p>
  
  <ul>
  <li>Ninject creates a Session and Opens a Transaction. </li>
  <li>Ninject injects repositories into services, and services into controllers.</li>
  <li>I make some changes to the properties and children of an object and save on the aggregate root.  This calls Transaction.Commit (works fine, as expected)</li>
  <li>In another method later in the controller, I try to save a separate object</li>
  <li>The second call fails because the transaction is no longer active.</li>
  </ul>
  
  <p>I'm thinking of adding a bool "CommitNeeded" to the UnitOfWork which would be set by my Save() method and conditionally trigger a Commit() on UnitOfWork.Dispose().  Is this a good idea?  </p>
  
  <p>Should I remove the transaction infrastructure?  Should I change my Commit()'s to Flush()'s?</p>
  
  <p>Any advice that would help fix my anti-pattern would be appreciated.</p>
  
  <hr>
  
  <p>In response to the comments - I guess I don't mind if they happen together or separate.  There are two things going on.  The first one changes a "Customer" object, and then saves it.  The second makes a logging entry which then calls the same "Save" method.</p>
  
  <pre><code>var Customer = ServiceLayer.GetCustomer(...);
  Transmogrify(Customer, Customer.Children, Widgets, ...);
  ServiceLayer.Save(Customer)
  
  ServiceLayer.RecordEvent(Customer, "Customer was frobbed")
  </code></pre>
  
  <p>where LogEvent looks like</p>
  
  <pre><code>public void RecordEvent(Customer customer, int eventTypeId, string description)
  {
      ...
  
      Save(customer);
  }
  </code></pre>
  
  <p>The RecordEvent method has its own "save" because it is called from other controllers that do no data changes.  I believe the Save call doesn't belong in either of those places.  The question is, where?  The Dispose() method of the Service Layer?  or a Filter like the other users suggested?</p>