<p>One of the things that get me thoroughly confused is the use of <code>session.Flush</code>,in conjunction with <code>session.Commit</code>, and <code>session.Close</code>.</p>

<p>Sometimes <code>session.Close</code> works, e.g., it commits all the changes that I need. I know I need to use commit when I have a transaction, or a unit of work with several creates/updates/deletes, so that I can choose to rollback if an error occurs.</p>

<p>But sometimes I really get stymied by the logic behind <code>session.Flush</code>. I have seen examples where you have a <code>session.SaveOrUpdate()</code> followed by a flush, but when I remove Flush it works fine anyway. Sometimes I run into errors on the Flush statement saying that the session timed out, and removing it made sure that I didn't run into that error.</p>

<p>Does anyone have a good guideline as to where or when to use a Flush? I've checked out the NHibernate documentation for this, but I still can't find a straightforward answer.</p>

[{'answer_id': 43567, 'author': 'Matt Hinze', 'author_id': 2676, 'author_profile': 'https://Stackoverflow.com/users/2676', 'pm_score': 9, 'selected': True, 'text': '<p>Briefly:</p>\n<ol>\n<li>Always use transactions</li>\n<li>Don\'t use <code>Close()</code>, instead wrap your calls on an <code>ISession</code> inside a <code>using</code> statement or <strong>manage the lifecycle of your ISession somewhere else</strong>.</li>\n</ol>\n<p>From <a href="http://nhibernate.info/doc/nh/en/index.html#manipulatingdata-flushing" rel="noreferrer">the documentation</a>:</p>\n<blockquote>\n<p>From time to time the <code>ISession</code> will execute the SQL statements needed to synchronize the ADO.NET connection\'s state with the state of objects held in memory. This process, flush, occurs by default at the following points</p>\n<ul>\n<li>from some invocations of <code>Find()</code> or <code>Enumerable()</code></li>\n<li>from <code>NHibernate.ITransaction.Commit()</code></li>\n<li>from <code>ISession.Flush()</code></li>\n</ul>\n<p>The SQL statements are issued in the following order</p>\n<ol>\n<li>all entity insertions, in the same order the corresponding objects were saved using <code>ISession.Save()</code></li>\n<li>all entity updates</li>\n<li>all collection deletions</li>\n<li>all collection element deletions, updates and insertions</li>\n<li>all collection insertions</li>\n<li>all entity deletions, in the same order the corresponding objects were deleted using <code>ISession.Delete()</code></li>\n</ol>\n<p>(An exception is that objects using native ID generation are inserted when they are saved.)</p>\n<p><strong>Except when you explicity <code>Flush()</code>, there are absolutely no guarantees about when the Session executes the ADO.NET calls, only the order in which they are executed</strong>. However, NHibernate does guarantee that the <code>ISession.Find(..)</code> methods will never return stale data; nor will they return the wrong data.</p>\n<p>It is possible to change the default behavior so that flush occurs less frequently. The <code>FlushMode</code> class defines three different modes: only flush at commit time (and only when the NHibernate <code>ITransaction</code> API is used), flush automatically using the explained routine, or never flush unless <code>Flush()</code> is called explicitly. The last mode is useful for long running units of work, where an <code>ISession</code> is kept open and disconnected for a long time.</p>\n</blockquote>\n<p>...</p>\n<p>Also refer to <a href="http://nhibernate.info/doc/nh/en/index.html#manipulatingdata-endingsession" rel="noreferrer">this section</a>:</p>\n<blockquote>\n<p>Ending a session involves four distinct phases:</p>\n<ul>\n<li>flush the session</li>\n<li>commit the transaction</li>\n<li>close the session</li>\n<li>handle exceptions</li>\n</ul>\n<h2>Flushing the Session</h2>\n<p>If you happen to be using the <code>ITransaction</code> API, you don\'t need to worry about this step. It will be performed implicitly when the transaction is committed. Otherwise you should call <code>ISession.Flush()</code> to ensure that all changes are synchronized with the database.</p>\n<h2>Committing the database transaction</h2>\n<p>If you are using the NHibernate ITransaction API, this looks like:</p>\n<pre><code>tx.Commit(); // flush the session and commit the transaction\n</code></pre>\n<p>If you are managing ADO.NET transactions yourself you should manually <code>Commit()</code> the ADO.NET transaction.</p>\n<pre><code>sess.Flush();\ncurrentTransaction.Commit();\n</code></pre>\n<p>If you decide not to commit your changes:</p>\n<pre><code>tx.Rollback();  // rollback the transaction\n</code></pre>\n<p>or:</p>\n<pre><code>currentTransaction.Rollback();\n</code></pre>\n<p>If you rollback the transaction you should immediately close and discard the current session to ensure that NHibernate\'s internal state is consistent.</p>\n<h2>Closing the ISession</h2>\n<p>A call to <code>ISession.Close()</code> marks the end of a session. The main implication of Close() is that the ADO.NET connection will be relinquished by the session.</p>\n<pre><code>tx.Commit();\nsess.Close();\n\nsess.Flush();\ncurrentTransaction.Commit();\nsess.Close();\n</code></pre>\n<p>If you provided your own connection, <code>Close()</code> returns a reference to it, so you can manually close it or return it to the pool. Otherwise <code>Close()</code> returns it to the pool.</p>\n</blockquote>\n'}, {'answer_id': 44212, 'author': 'Sean Carpenter', 'author_id': 729, 'author_profile': 'https://Stackoverflow.com/users/729', 'pm_score': 4, 'selected': False, 'text': "<p>Starting in NHibernate 2.0, transactions are required for DB operations.  Therefore, the <code>ITransaction.Commit()</code> call will handle any necessary flushing.  If for some reason you aren't using NHibernate transactions, then there will be no auto-flushing of the session.</p>\n"}, {'answer_id': 13252242, 'author': 'Paul T Davies', 'author_id': 803418, 'author_profile': 'https://Stackoverflow.com/users/803418', 'pm_score': 0, 'selected': False, 'text': '<p>Here are two examples of my code where it would fail without session.Flush():</p>\n\n<p><a href="http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html" rel="nofollow noreferrer">http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html</a></p>\n\n<p>at the end of this, you can see a section of code where I set identity insert on, save the entity then flush, then set identity insert off. Without this flush it seemed to be setting identity insert on and off then saving the entity. </p>\n\n<p>The use of Flush() gave me more control over what was going on.</p>\n\n<p>Here is another example:</p>\n\n<p><a href="https://stackoverflow.com/questions/12494943/sending-nservicebus-message-inside-transactionscope">Sending NServiceBus message inside TransactionScope</a></p>\n\n<p>I don\'t fully understand why on this one, but Flush() prevented my error from happening.</p>\n'}, {'answer_id': 22193504, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 1, 'selected': False, 'text': "<p>From time to time the ISession will execute the SQL statements needed to synchronize the ADO.NET connection's state with the state of objects held in memory.</p>\n\n<p>And always use </p>\n\n<pre><code> using (var transaction = session.BeginTransaction())\n {\n     transaction.Commit();\n }\n</code></pre>\n\n<p>after the changes are committed than this changes to save into database we use  transaction.Commit();</p>\n"}]
['https://Stackoverflow.com/questions/43320', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/372/']