Can anyone give me a quick overview of using TransactionScope with NHibernate? Do I need to do anything special with the session/IEnlistmentNotification/etc. to get this to
According to Fabio Maulo in comments related to NH-2107:
You can use TransactionScope and you should continue using NH's transaction too. Where you have read that the Usage of TransactionScope mean the avoid of usage of NH's transaction ?
I would have assumed that explicit usage of NHibernate's transactions not necessary, but aparently that's best practice
Also, if you are using TransactionScope, upgrade to NHibernate 2.1. It is only with 2.1 that NH really gotten good integration with TransactionScope.
I believe you can replace NHibernate transactions with this as long as you respect some constraints as some have already said:
I hope that's all ;-)
PS: I added the Oracle details because they where my concern and others might benefit.
The above works OK provided you are using a connection provider that supports the use of a Light-weight Transaction Manager, such as SQL Server 2005/2008.
If you are using SQL Server 7/2000 then all of your transactions will become Distributed Transactions even if you only hit one database/resource. This is probably not what you would want in most cases, and will be expensive performance wise.
So checkout if your connection provider and database server combination are suitable for use with TransactionScope.
I have been using nHibernate 2.1 for awhile, and after a few production issues and trying quite a few variations, we have settled on the following method, as per Avoiding Leaking Connections With NHibernate And TransactionScope:
using (var scope = new TransactionScope(TransactionScopeOption.Required))
{
using (var session = sessionFactory.OpenSession())
using (var transaction = session.BeginTransaction())
{
// do what you need to do with the session
transaction.Commit();
}
scope.Complete();
}
As we are using MSMQ and WCF so we had to use the ambient transaction.
We found that not using session.BeginTransaction() caused a connection leak. We also found that re-using a session after committing a transaction caused a race condition (nHibernate is not thread safe and DTSC Commits/Rollbacks occur on a background thread).
I've testing this out using varying vendors and it just works. If you don't have "scope.Complete()" then the transaction will roll back. You may need to have MSDTC running the machine(s) involved if there is more than one durable resource. In that case MSDTC will automatically detect the ambient ADO.NET transactions and manage the whole thing.