-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: NHibernate with COM+ distributed transaction
PostPosted: Tue Feb 07, 2006 11:36 am 
Regular
Regular

Joined: Thu May 12, 2005 10:12 am
Posts: 71
Location: Buenos Aires, Argentina
Hi, Just wanted to note a nice article I found on this topic discussed a time ago (while NH was still beta).

Here is the link :http://www.codeproject.com/useritems/complus_nhibernate_trans.asp


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 08, 2006 5:29 am 
Regular
Regular

Joined: Fri Jun 11, 2004 6:27 am
Posts: 81
Location: Yaroslavl, Russia
Some criticism of this article:

1. ElistIfPossible is very expensive because it uses the Reflection.

2. If we will look at the example Save method, that is intended to show the princple, we see that session is opened after a transaction is possible started. Usually, a connection is opened by Session object somewhere after opening of a session. This means that manual enlisting is not really necessary, because if connection provider supports distributed transactions and a connection is opened in scope of transaction, then the connection will be enlisted automatically.

3. It's better to create service class that implements IDisposable. It will enter a transaction context on creation and leave on disposing. Using of "using" construct is simplier, than "try - catch".

I was posting a text and sources for similar approach to the old wiki. Now it's here - http://www.hibernate.org/363.html, but i don't see sources. If people need it, then i can repost them to the new wiki.

_________________
Best,
Andrew Mayorov // BYTE-force


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 08, 2006 5:39 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
I recently found out that NHibernate will probably not work correctly with distributed transactions out-of-the-box. The problem is that NHibernate does not get notified when a distributed transaction ends, SessionImpl.AfterTransactionCompletion is not called, and so second-level cache may be left in inconsistent state, and LockModes for entities will not be reset.

I'm not 100% sure about this, so if anybody can confirm or deny it, I would be grateful. My current idea for a fix is writing a compensating resource manager for the session because it looks like this is the only way to get notified about transaction status in .NET 1.1.

To Andrew: I didn't find a good place to put your sources to, and I didn't want to just paste them onto the page since it would make the page unreadable. I'll put them on nhibernate.sf.net and link from the page.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 08, 2006 8:55 am 
Regular
Regular

Joined: Fri Jun 11, 2004 6:27 am
Posts: 81
Location: Yaroslavl, Russia
Sergey, i think you are right: it shouldn't work correctly now. But there are two points:
1. Discussed article (as well as my code) was written long ago. In former times AfterTransactionCompletion was not doing anything apparently useful, so, perhaps, it was not necessary to call it. :)
2. I widely use distributed transaction w/o calling of this method and haven't hit problems with it. Perhaps, they have very small impact.

I think as a quick solution, we can manually track sessions, enlisted in the transaction, and call AfterTransactionCompletion, in the end of it. Anyway, we manually enter and leave transaction context.

As for my sources, i think it's better not to publish them now. They are not very fresh already. :) At the same time, i think it's better to publish sources right onto the page. At least in the old wiki it produced more useful result. Classes are not that large. Though, it's better to create special page for distributed transactions and not to place everything on the page about ASP.NET.

_________________
Best,
Andrew Mayorov // BYTE-force


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 08, 2006 9:44 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
I already uploaded the sources to nhibernate.sf.net and linked to them on the page. By the way, feel free to edit that page and others in the Community Area, everybody has rights to edit pages in the area.

NHibernate will work correctly with COM+ transactions if two requirements are fulfilled:
- the second-level cache is disabled (it might actually work with second-level cache enabled in some circumstances, but it's uncertain)
- there's only one transaction in each session and each session is discarded after completing the transaction.

If you call AfterTransactionCompletion yourself, then everything should work fine. You will have to cast ISession to ISessionImplementor to get access to that method though.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 08, 2006 12:37 pm 
Regular
Regular

Joined: Fri Jun 11, 2004 6:27 am
Posts: 81
Location: Yaroslavl, Russia
Thank you, Sergey! I will try to think how and when can i call AfterTransactionCompletion manually. I'm uncertain, because there could be several situations:
1. Begin transaction, connect session to the database, do the work, close connection, commit or rollback transaction.
2. Connect session, begin transaction, do the work, commit or rollback, disconnect.
3. Begin transaction, begin transaction, ... . Plus more cases like this one.

It seems to me that in second case AfterTransactionCompletion will be quite ok at the end of the transaction. This scenario is very similar to usual NH transactions.

Will 1st case work correctly? At the end of the transaction session will be already disconnected. Could it be a problem?

And it goes even more complex in other cases. At the end of each transaction should i call this method? Actually, only outermost transaction could tell if operation as a whole comitted or rolled back. But this transaction could span several sets of interactions with session. And even several connect/disconnect pairs. What do you think?

_________________
Best,
Andrew Mayorov // BYTE-force


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 10:00 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Actually, Close and Disconnect both call AfterTransactionCompletion, if the session does not have a current transaction (otherwise the transaction itself should call the method). Close and Disconnect both call it with success=false, so the code assumes that there was a failed transaction.

Calling AfterTransactionCompletion on a closed session will work, and calling AfterTransactionCompletion twice should not cause any harm either.

So, I'm now not sure if there is any serious error here, take this just as a warning, a possibility that you should keep in mind.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 10:54 am 
Regular
Regular

Joined: Fri Jun 11, 2004 6:27 am
Posts: 81
Location: Yaroslavl, Russia
Definitely, this is the inconsistency between NH and distributed transaction: session always thinks that it is bigger than transaction, while it could be wrong. And i don't see obvious ways to work it around. Let's take the example:
1. Start a transaction.
2. Connect the session to the database.
3. Perform some work.
4. Call AfterTransactionCompletion( true ), because we are going to disconnect the session and we know, that session will call this method with "false". So far transaction was ok, so we decide to tell session that transaction has already completed successfully.
5. Close the session.
6. Rollback the transaction.

Looks like we have a problem at step 6 - database state will be rolled back, but session will think that it was a success.

_________________
Best,
Andrew Mayorov // BYTE-force


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.