views:

115

answers:

4

I'd like to ensure that when I'm persisting any data to the database, using (Fluent)NHibernate, that the operations are executed inside a transaction. Is there anyway of checking that a transaction is active via an interceptor? Or any other eventing mechanism?

More specifically, I'm using the System.Transaction.TransactionScope for transaction management, and just want to stop myself from not using it.

A: 

To what end? NHProf will give you warnings if you're not executing inside a transaction. Generally you should be developing with this tool open anyway...

HTH,
Kent

Kent Boogaart
Had forgotten about NHProf, but I am looking for a programatic solution here. NHProf won't always be open, and won't always be on everyones machine. The fact NHProf can detect it, is indication it can be done, I'd just like to know how.
pms1969
+1  A: 

I haven't tried this, but I think you could create a listener implementing IFlushEventListener. Something like:

    public void OnFlush(FlushEvent @event)
    {
        if ([email protected])
        {
            throw new Exception("Flushing session without an active transaction!");
        }
    }

It's not clear to me (and Google didn't help) exactly when OnFlush is called. There also may be an implicit transaction that could set IsActive to true.

Jamie Ide
Thanks Jamie, I'll try this.
pms1969
tobsen
A: 

If you had one place in your code that built your session, you could start the transaction there and fix the problem at a stroke.

James L
not really. I don't really want to control the transaction there (more at the point of the updates/inserts), as I don't want the overhead of a transaction on selects (and that's the majority of work that will be done.
pms1969
Why don't you want transactions around on selects? They need to be isolated too.
James L
Unless I'm mistaken, transactions are a means of ensure data consistancy. Since selects don't change data, and most of the time I'll just be reading information in order to display it on a page/screen, I therefore don't need a transactionscope.Agreed, that if I'm updating and reading at the same time, the selects will most likely exist in the same transaction, but generally, for select only scenarios, I don't want or need the overhead of setting up an explicit transaction.
pms1969
The problem comes when you select more than one piece of data. Another transaction can intervene between successive reads, and make the two reads inconsistent with each other. It is considered best practice to wrap every 'unit of work' from beginning to end in a transaction. Otherwise, each statement runs in its own implicit transaction. It's certainly no more efficient!
James L
Fair call, I hadn't considered it like. And on reflection this is probably just the easiest way to go anyway. Thanks for your input James.
pms1969
A: 

If you had been using Spring.Net for your transaction handling, you could use an anonymous inner object to ensure that your DAOs/ServiceLayer Objects are always exposed with a TransactionAdvice around their service methods. See the spring documentation for an example.

tobsen