I am trying to use NHibernate with legacy entities that are not mapped with NHibernate. On occasion this means that I need to manually flush NHibernate data to the database so that I don't receive foreign key exceptions when I try to connect the legacy entities with NHibernate-mapped entities.
A problem occurs when this takes place within a transaction that then needs to be rolled back. The data flushed from NHibernate does not rollback.
Is there anything I can do about this?
UPDATE
Still curious how to do this - I don't believe either of the answers given address the issue. I need to call Flush(). The question is, how do I rollback data that has been flushed?
check this: Force query execution without flush/commit
I seemed to have the same problem, i would flush and then i would rollback but some data would remain persisted in the database. However, there were some parts in my code that would call a commit, which cannot be rolled back. Consider the accepted answers' code snippet as the proper usage for transactions, flushes, rollbacks and commits and take into consideration that this pattern can be extended...
in a single unit of work (ie we consider a Request in a web application as a single unit of work and everything that happens in that request exists in a single transaction which onEndRequest is committed):
you call _sessionFactory.OpenSession()
, _session.BeginTransaction()
, _session.CommitTransaction()
and _session.CloseSession()
only once.
you can call _session.Flush()
and _session.RollBackTransaction()
as many times as you want, but Flush() is automatically called on Commit automatically. You may want to call a Flush when you need to make a query and ensure that the data fetched will not be stale.
Note that once a commit transaction is committed, all operations afterwards do not happen on that transaction. Instead NHibernate will create the necessary transaction under the hood (http://www.nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions) in which point you already have problems tracking consistency and possibly logical integrity
If you really must call commit in the middle of your unit of work it is strongly advised to create a new transaction at that point so you can manage it explicitly
What's even better is to try out Nested Transactions will allegedly allow partial commits; you can rollback the "root" transaction and all changes will be reverted. I haven't really tested this feature of .NET and SQL Server, although the nested transaction in the database itself leaves a lot to be desired and i don't know how exactly ADO.NET instruments this feature.
points 1 to 4 have been tested with all versions of NHibernate starting from 1.2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With