-->
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: Commit point of the Application Transaction in Ch8 /w filter
PostPosted: Tue Nov 23, 2004 8:28 pm 
Newbie

Joined: Tue Nov 23, 2004 8:20 pm
Posts: 2
In chapter 8, there is an example showing the usage of a ServletFilter to demonstrate the Application Transaction issue. I'm fond of this approach in my current project however I got confuse of the reason of the commitTransaction after the doFilter. Though it is the Application Transaction, the transaction should be commit in some command/action that is knowledgable the end point of the application transaction. Please comment or is there any stuff i miss?

Thanks,

Besides, I love your book coz' it not only cover the usage of the Hibernate but also the design consideration of the Hibernate.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 24, 2004 3:54 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
The "theory" behind App Tx is in chapter 5.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 24, 2004 2:25 pm 
Newbie

Joined: Tue Nov 23, 2004 8:20 pm
Posts: 2
I don't know the exact meaning of the commit sentence in the middle of the doFilter() (p326). If we plan to do the application transaction, what is the reason to commit the transaction. Please give me a hinit.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 24, 2004 2:27 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Because a database transaction has a different granularity. Really, this is all explained very extensively in chapter 4.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 24, 2004 2:28 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Eh, chapter 5 of course.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 19, 2005 11:05 am 
Regular
Regular

Joined: Mon Jul 26, 2004 2:28 pm
Posts: 86
Location: Pensacola, Florida
I was a little confused on this point as well. What I gathered is this:

1. An application transaction consists of one or more database transactions
2. The scope of a database transaction should be the same as the scope of a Hibernate transaction
3. A best practice is to limit the scope of a Hibernate transaction to the scope of a request cycle in a web application. Subsequently, a Hibernate transaction (and subsequently the database transaction) should be committed at the end of every request cycle.
4. The application transaction ends when the Hibernate session is closed (or cleared)
5. Ergo, the scope of an application transaction is the same as the scope of a Hibernate session

First, is that correct? I am using user-supplied connections, so I have to explicitly call session.connection( ).commit( ), which means the scope of my Hibernate transactions do not necessarily have to coincide with the scope of my database transactions. Is this the case using managed connections (ala C3P0) as well? Or does a Transaction.commit( ) call commit( ) automatically, thus forcing the scopes to be the same?

Second, if I am correct in assuming that the scope of a Hibernate transaction is the same as that of a database transaction, then I am a little uncertain as to how to handle a failed application transaction. For example, this sequence of events occurs often in our applications:

Request 1: Object is loaded and cached in the Hibernate session. Object is passed to the view, where forms are rendered and pre-populated
Request 2: User submits modifications to the data. These are passed to the business layer and validated. If the data is invalid, messages are generated, passed back up to the View, and rendered (Repeats until data is correct). Otherwise, data is committed and the session is closed.

A commit at the end of Request 1 never hurts, since the only operation performed is a load. A commit at the end of Request 2 is allowable, provided the data is correct. However, if the data is invalid, then the commit may result in a HibernateException (via a SQLException) in the best case, or invalid data (worst case).

To combat this, I have come up with a pattern along the lines of the filter provided in the book, with the following exceptions:

1. I have created a session bean that stores a Hibernate session and Hibernate transaction. This is stored in the user's HTTP session.
2. At the start of each request, I ensure that the session bean contains an open, connected session, and an uncommitted transaction. The session is then copied into a ThreadLocal variable for convenience.
3. During the request, the commitTransaction or rollbackTransaction is called on the session bean to set a flag and "schedule" the commit/rollback of a transaction and closure of the session
4. At the end of the request, if a commit/rollback has been "scheduled", the transaction is committed or rolled back, and the session is closed.

In this pattern, the Hibernate transaction has the same scope as the session, and allows for an all-or-nothing application transaction.

Do you see any pitfalls to this approach? (I tend to come up with anti-patterns...I was unwittingly using session-per-application until very recently).

P.S. The book is awesome...not only did it explain Hibernate, but it really opened my eyes to ORM issues in general. Great read.

- Jesse


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 19, 2005 11:14 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
A failed application transaction can only be "rolled back" if ony the last database transaction in this app tx has been writing data. Therefore it can be rolled back, which would effectively roll back the work done in the app tx. To program with this paradigm (which is not always possible) use FlushMode.NONE.

You can also see an app tx as something that you have to implement completely, on top of the given transaction infrastructure. This would then include not only "forward" processing, but also compensation actions ("undo") you can execute if needed.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 19, 2005 11:53 am 
Regular
Regular

Joined: Mon Jul 26, 2004 2:28 pm
Posts: 86
Location: Pensacola, Florida
Wow. Thanks for the quick reply!

After some more thought I realized that it is probably preferrable to use a separate view object, analogous to a Struts Form, to perform updates/validations on. Thus you load the object; populate the Form object (or JSF bean, or whatever, perhaps using BeanUtils to simplify the copy logic); do all of your back-and-forth stuff with the user using the form; and finally copy the form data into the persistent object once you are ready to write it. This is compatible with session-per-request or session-per-application-transaction, the latter necessary only if you have lazy loading objects and want to avoid explicit reattachment.

Unfortunately, this is more code (either an XML DynaActionForm in Struts or another POJO at the very least), and there are some complications to consider (dynamically adding child elements, etc.), but it does make the application transaction logic a lot cleaner and eminently undo-able.

(This is probably what was meant by "passing up" detached objects to the view layer...I didn't make the connection at first. Obviously integration into an MVC architecture is beyond the scope of the book, but this post might help out some other forum users when choosing a design)

Thanks again,

- Jesse


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.