In NHibernate 3.0, FlushMode.Auto
does not work when running under an ambient transaction only (that is, without starting an NHibernate transaction). Should it?
using (TransactionScope scope = new TransactionScope())
{
ISession session = sessionFactory.OpenSession();
MappedEntity entity = new MappedEntity() { Name = "Entity", Value = 20 };
session.Save(entity);
entity.Value = 30;
session.SaveOrUpdate(entity);
// This returns one entity, when it should return none
var list = session.
CreateQuery("from MappedEntity where Value = 20").
List<MappedEntity>();
}
(Example shamelessly stolen from this related question)
In the NHibernate source I can see that's it's checking whether there's a transaction in progress (in SessionImpl.AutoFlushIfRequired
), but the relevant method ( SessionImpl.TransactionInProgress
) does not consider ambient transactions - unlike its cousin ConnectionManager.IsInActiveTransaction
, which does consider ambient transactions.
Good news. Thanks to Jeff Sternal (who nicely identified the problem) I updated https://nhibernate.jira.com/browse/NH-3583 and thanks to the NH staff, there's already a fix and a pull request so in the upcoming release 4.1.x.x this ISSUE will be fixed.
You should use an explicit NHibernate transaction always.
using (TransactionScope scope = new TransactionScope())
using (ISession session = sessionFactory.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
//Do work here
transaction.Commit();
scope.Complete();
}
I see you also wrote in the NH dev list - while this can change in the future, that's how it works now.
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