Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I do nested transactions in NHibernate?

Can I do nested transactions in NHibernate, and how do I implement them? I'm using SQL Server 2008, so support is definitely in the DBMS.

I find that if I try something like this:

using (var outerTX = UnitOfWork.Current.BeginTransaction())
{
    using (var nestedTX = UnitOfWork.Current.BeginTransaction())
    {
        ... do stuff
        nestedTX.Commit();
    }

    outerTX.Commit();
}

then by the time it comes to outerTX.Commit() the transaction has become inactive, and results in a ObjectDisposedException on the session AdoTransaction.

Are we therefore supposed to create nested NHibernate sessions instead? Or is there some other class we should use to wrap around the transactions (I've heard of TransactionScope, but I'm not sure what that is)?

I'm now using Ayende's UnitOfWork implementation (thanks Sneal).

Forgive any naivety in this question, I'm still new to NHibernate.

Thanks!

EDIT: I've discovered that you can use TransactionScope, such as:

using (var transactionScope = new TransactionScope())
{
    using (var tx = UnitOfWork.Current.BeginTransaction())
    {
        ... do stuff
        tx.Commit();
    }

    using (var tx = UnitOfWork.Current.BeginTransaction())
    {
        ... do stuff
        tx.Commit();
    }

    transactionScope.Commit();
}

However I'm not all that excited about this, as it locks us in to using SQL Server, and also I've found that if the database is remote then you have to worry about having MSDTC enabled... one more component to go wrong. Nested transactions are so useful and easy to do in SQL that I kind of assumed NHibernate would have some way of emulating the same...

like image 921
Gavin Avatar asked Jul 28 '09 05:07

Gavin


People also ask

Can transactions be nested?

A nested transaction is used to provide a transactional guarantee for a subset of operations performed within the scope of a larger transaction. Doing this allows you to commit and abort the subset of operations independently of the larger transaction.

Does Oracle support nested transactions?

Oracle doesn't support nested transactions. If a transaction commits, it commits. That's why you generally don't want to commit (or rollback) a transaction in a stored procedure, that makes it difficult to reuse the procedure elsewhere if your transaction semantics differ.

What are the advantages of nested transactions?

Advantages of Nested Transactions 1. Nested transactions allow for a simple composition of subtransactions improving modularity of the overall structure. 2. The concurrent execution of subtransactions that follow the prescribed rules allows for enhanced concurrency while preserving consistency.

What is NHibernate flush?

Flushing synchronizes the persistent store with in-memory changes but not vice-versa. Note that for all NHibernate ADO.NET connections/transactions, the transaction isolation level for that connection applies to all operations executed by NHibernate!


1 Answers

NHibernate sessions don't support nested transactions.

The following test is always true in version 2.1.2:

var session = sessionFactory.Open();
var tx1 = session.BeginTransaction();
var tx2  = session.BeginTransaction();
Assert.AreEqual(tx1, tx2);

You need to wrap it in a TransactionScope to support nested transactions.

MSDTC must be enabled or you will get error:

{"Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool."}

like image 146
Sathish Naga Avatar answered Sep 29 '22 22:09

Sathish Naga