Hi All,

I'am trying to find out the best practices for using
System.Transactions.TransactionScope with NHibernate.
I have created some unit tests to find out what works and what doesn't
work. I am stuck with a couple of questions:

First, when I execute the following code (sorry for dutch naming):

[TestMethod]
public void CanCommitNestedTransactionWhenOuterTransactionIsAborted()
{
        long medewerkerId1 = 2;
        long medewerkerId2 = 3;
        string voornaam1;
        string voornaam2;

        // NHibernate Session will be openend on first call to repository

        IMedewerkerRepository repository = this.CreateRepository();

        using (TS.TransactionScope scope1 = new TS.TransactionScope()) {
                // Update m1 in scope1.
                Medewerker m1 = repository.Get(medewerkerId1);
                voornaam1 = m1.Voornaam;
                m1.Voornaam = DateTime.Now.ToString();
                repository.Update(m1);

                // Update m2 in nested scope2 -> RequiresNew
                using (TS.TransactionScope scope2 = new TS.TransactionScope
(TransactionScopeOption.RequiresNew)) {
                        Medewerker m2 = repository.Get(medewerkerId2);
                        voornaam2 = m2.Voornaam;
                        m2.Voornaam = DateTime.Now.ToString();
                        repository.Update(m2);

                        scope2.Complete(); // scope 2 is completed
                }

                //NB: scope1 is not completed
        }

        Medewerker mCheck1 = repository.Get(medewerkerId1);
        Medewerker mCheck2 = repository.Get(medewerkerId2);

        Assert.AreEqual(voornaam1, mCheck1.Voornaam);
        Assert.AreNotEqual(voornaam2, mCheck2.Voornaam);

        // TestCleanup will dispose session
}

So scope1 should not be commited and scope2 should (in my opinion) be
committed because it is a seperate transaction (RequiresNew). To my
supprise both scopes are not committed, why, isn't RequiresNew
supported by NHibernate?

Second question:

Consider the following test:

[TestMethod]
public void CanRollbackTransaction() {
        long medewerkerId = 2;
        string voornaam;

        // NHibernate Session will be openend on first call to repository

        IMedewerkerRepository repository = this.CreateRepository();

        using (TS.TransactionScope scope = new TS.TransactionScope()) {
                Medewerker m = repository.Get(medewerkerId);
                voornaam = m.Voornaam;

                m.Voornaam = DateTime.Now.ToString();

                repository.Update(m);

                //NB: scope is not completed
        }

        Medewerker mCheck = repository.Get(medewerkerId);

        Assert.AreEqual(voornaam, mCheck.Voornaam);

        // TestCleanup will dispose session
}

This test does not pass although scope is rollbacked in the database.
It looks like the session cache does not get updated (no call to db in
NHProf). The second "Get" gets it's value from the cache and that
still is the updated (but rollbacked) data. When I create my own
wrapper arround TransactionScope and call ISession.Clear() on the
current NHibernate session the test passes. But is this the way to go?

I am a bit stuck on how to use System.Transactions.TransactionScope
with NHibernate. I need to use the TransactionScope class because of
other db activity outside NHibernate in the same transaction.

Kind regards,
Henk Huisman
-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.


Reply via email to