-->
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.  [ 4 posts ] 
Author Message
 Post subject: Hibernate, Transactionality, & Concurrency
PostPosted: Thu Mar 18, 2004 2:43 pm 
Newbie

Joined: Thu Mar 18, 2004 2:35 pm
Posts: 1
Hibernate of course implements threadsafe SessionFactory objects that can be used to create non-threadsafe Session objects. You can blindly try to keep Session objects open as long as possible (to improve performance reaching the database through keeping active and pooled connections open) in a multithreaded Java application by implementing ThreadLocal variables, but that background information isn't really important to know. What is important to know is that you can't have any one ORM'ed object open across multiple Hibernate sessions, and this presents a bit of a challenge. :)

The reason that one can't have an ORM'ed object open across mutliple Hibernate sessions has to do with database transactionality and object concurrency. To provide more insight, here's an example scenario:

Quote:
The players: One ORM'ed Java object, obj1, instance of MyObject. The MyObject class defines two properties, property1 & property2.

1. Java application #1 grabs a copy of obj1 to play with.

2. Java application #2 also grabs a copy of obj1 from the database.

3. Java application #1 makes a change to property1 of the object and saves the object back into the database with the updated goods.

4. Java application #2 makes a change to property2 of the object and also saves the object back into the database. Unfortunately, property1 of the object has been overwritten to the value of step #1 above, and furthermore Java application #1 doesn't know about the update made, after it got its copy, to property2 of the object.


This race condition doesn't exist in well-made applications with hand coded JDBC calls, because one can intelligently design their SQL UPDATE clauses; however, with objects stored in memory in addition to the back-end database, this really moves the need for transactionality out of the database and up into the ORM layer of a given Java application. Row level locking at the database is no longer an option to keep property values safe, and Hibernate instead needs to know about what's happening.

Well, Hibernate isn't transaction-aware. Sessions aren't threadsafe, and even if they were, two separate Java applications running on two separate machines would present quite a problem with this architecture. There are a couple of possible solutions presented at the following location:

http://www.hibernate.org/hib_docs/refer ... tions.html

However, I don't like these. :) That page reads, "[t]he only approach that is consistent with high concurrency and high scalability is optimistic locking with versioning. Hibernate provides for three possible approaches to writing application code that uses optimistic locking."

The three approaches include (17.3.1) one long session with automatic versioning, (17.3.2) many sessions with automatic versioning, and (17.3.3) application version checking. 17.3.1 really applies to rolling multiple transactions into one big transaction and has to do more with a need born out of crap application design. Not only that, but 17.3.1 with its "long session" approach doesn't account for multiple sessions spread across multiple Java applications / JVM instances, of course. 17.3.2 outlines a way of using a Hibernate Session's saveOrUpdate() method to make sure an object isn't saved as a new row to the database because it was initially loaded in another Session. This is also crap, and for me this is really just presenting a way to allow persistent objects to span multiple Session's -- one session for loading the object and another for saving it. Perhaps this approach opens up a door and allows something to be built in the application to overcome transactionality issues, but this puts a lot of extra burden on the developer, and I'd rather hand code JDBC calls. Now 17.3.3 is good, because it presents an approach whereas the object is reloaded from the database before any changes are made to that object, but as sexy as this approach may seem, what if the two Java applications running against the same database are making overlapping updates? This approach doesn't provide a solution to that, ** unless any individual row in the database that corresponds with an ORM'ed object within the system is shared as common instantiated object across all the running JVMs **.

Phwew, that was a lot of explaining. I do hope that all makes sense. :)

So to overcome these issues, and perhaps my own lack of understanding with regards to how transactionality can be achieved using an easier approach, I think that sharing each unique ORM'ed object in the system (which will in turn correspond with a unique row in one of the database tables) across any and all Java applications running against that database will help.

Does anyone know of a way whereas I can have two Java applications on two separate machines (each will be running on top of its own JVM, of course), each working with an object yet sharing all of that objects properties by providing an update to the other machine / JVM when a property is changed?

Is this something that EJBs provide? I've heard that EJBs are transaction safe and stuff. I don't know much about this EJB stuff (yet), but I think I need some if its goodness to make ORM work right. What does everyone think? Can someone give me a quick run-down on how EJBs might or might not help, or help to explain some other possible solutions to this stuff?

Any ideas, full or partial, helpful or not, would be very much welcome.

Thanks so much in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 18, 2004 3:51 pm 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
create new Object per transaction and new transaction/session per thread and you will not have more conccurency problems than with JDBC.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 24, 2004 6:51 am 
Newbie

Joined: Mon Mar 22, 2004 5:45 am
Posts: 8
Location: Prague, Czech Republic
I don't quite understand Your issue with the 17.3.2 approach.

In one session, user loads object.
In another session she tries to update it. Hibernate automatically issues the update command:
update my_table set value1=?, value2=? where ID=? and version=?

Now, in case when the row had been changed meanwhile by other user (JVM) the StaleObjectException will be thrown, thus the user must edit the row again and issue the update command again.

Just simple optimistic concurrency control.

To share object and its properties by many JVM concurrently might lead to pretty mess.

BR,

Marcel

_________________
Marcel Kruzel
Trema (Czech Republic)
www.trema.com


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 24, 2004 8:32 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
You can use optimistic locking with hibernte, but it is optional feature.
It is not "academic" optimistc locking, but it can be usefull in practice.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.