views:

88

answers:

2

I have a suite of integration tests that run inside transactions. Sometimes it seems that NHibernate transactions are not being correctly rolled back. I can't work out what causes this.

Here is a slightly simplified overview of the base class that these integration test fixtures run with:

public class IntegrationTestFixture
{
    private TransactionScope _transactionScope;
    private ConnectionScope _connectionScope;

    [TestFixtureSetUp]
    public virtual void TestFixtureSetUp()
    {
        var session = NHibernateSessionManager.SessionFactory.OpenSession();
        CallSessionContext.Bind(session);
        _connectionScope = new ConnectionScope();
        _transactionScope = new TransactionScope();
    }

    [TestFixtureTearDown]
    public virtual void TestFixtureTearDown()
    {
        _transactionScope.Dispose();
        _connectionScope.Dispose();
        var session = CurrentSessionContext.Unbind(SessionFactory);
        session.Close();
        session.Dispose();
    }
}

A call to the TransactionScope's commit method is never made, therefore how is it possible that data still ends up in the database?

Update I never really got my head around the way NHibernate treats transactions but I found that calling Session.Flush() within a transaction would sometimes result in the data remaining in the database, even if the transaction is then rolled back. I am not sure why you can't call Flush, but then roll back. This is a pity because during integration testing you want to be able to hit the database and flush is the only way to do this sometimes.

+2  A: 

I had an issue with using the Identity generator that sounds similar. In a nutshell, when saving an object using an identity generator, it has to write to the database in order to get the identity value and can do this outside a transaction.

Ayende has a blog post about this.

g .
A: 

I'm having the same issue with some integration test that I'm trying to write at the moment. Did you ever managed to find a resolution to the problem?

Paul
Added an update. I think it is to do with calling Flush(). One would expect to be able to call Flush() but still rollback the transaction but this is not the case.
cbp