-->
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.  [ 15 posts ] 
Author Message
 Post subject: Hibernate and Container Managed Transactions
PostPosted: Mon Apr 07, 2008 1:54 pm 
Newbie

Joined: Mon Apr 07, 2008 1:32 pm
Posts: 7
I've read all the "How to ask for help" section, but couldn't find any specific solution to an issue I face.

I'm using a -

Session Bean -> DAO -> DB

approach, wherein the DAO has the hibernate methods only, but the transactions should be managed in the Session Bean. I'm using Weblogic and letting the container manage the Hibernate transactions.

When I do something like,

    1) Create 10 objects, and then in another method,
    2) Read the 10 objects,


sufficiently fast, the objects that the step 2 method returns are from the first-level cache, and are not the latest objects from the database.

However, If I wait a second or two, before reading the 10 objects, they come up fine. Does any one have a solution to this issue? (without using thread.sleep or session.clear()).

Also, is it reasonable to assume that the Hibernate Session is closed after every method call in my Session Bean (all methods have "Required", as the transaction attribute).

Thank you!


Top
 Profile  
 
 Post subject: Re: Hibernate and Container Managed Transactions
PostPosted: Mon Apr 07, 2008 5:12 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
Are they two different sessions in step one and two?


Farzad-


Top
 Profile  
 
 Post subject: Re: Hibernate and Container Managed Transactions
PostPosted: Tue Apr 08, 2008 11:54 am 
Newbie

Joined: Mon Apr 07, 2008 1:32 pm
Posts: 7
farzad wrote:
Are they two different sessions in step one and two?


Farzad-


Hi Farzad,

Thanks for replying.

Since I'm using CMT, the test does not create a session, rather it invokes two methods (create and find) in the session bean, assuming that they would create their own individual sessions via the container.

However, when the test is run, neither does the create method persist objects into the database, nor does the find method find any records in the database (since none were inserted anyway).

Thanks,

Gavin


Top
 Profile  
 
 Post subject: Re: Hibernate and Container Managed Transactions
PostPosted: Tue Apr 08, 2008 12:13 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
What is the transaction isolation level for db connections? I am guessing you run into this because the first one is still going through a commit process and the isolation level is something different from read uncommitted. I will be surprised if it is a L1 cache problem since there is no cache when a new session is created so you should see selects in output if show_sql is true.



Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 08, 2008 12:22 pm 
Newbie

Joined: Mon Apr 07, 2008 1:32 pm
Posts: 7
The transaction isolation level hasn't been configured in Weblogic. We are getting connections from a JDBC connection pool, configured in Weblogic.

I agree with you that the first one is in the commit process while the second executes. But since I'm using CMT, shouldn't the commit process happen immediately at the end of the method.

A colleague of mine, found out that if we do not set the session object in the HibernateUtil class to 'threadLocal', the create and find works allright.

Since the session is not threadLocal, this could lead to thread issues. But maybe not, if a new session is created for every Session bean method. Do you know if this is true, Farzad?

Thanks,

Gavin


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 08, 2008 12:43 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
Quote:
The transaction isolation level hasn't been configured in Weblogic. We are getting connections from a JDBC connection pool, configured in Weblogic.


Try setting the isolation level there.

Quote:
I agree with you that the first one is in the commit process while the second executes. But since I'm using CMT, shouldn't the commit process happen immediately at the end of the method.


That's my understanding too, but there are different softwares involved here. Some databases might tend to be a little bit non blocking, like MySQL delayed inserts and I am not aware how commit is handled on both sides (Java, DB). I don't know how fast your fast enough is but if it is in order of seconds then we have a problem. If it is in order of milliseconds then you might want to overlook that.

Quote:
A colleague of mine, found out that if we do not set the session object in the HibernateUtil class to 'threadLocal', the create and find works allright.


This is very suspicious since in your case it should not make a different. What is the sequence of method calls in the first step?

Quote:
Since the session is not threadLocal, this could lead to thread issues. But maybe not, if a new session is created for every Session bean method. Do you know if this is true, Farzad?


A new session is made for every bean method call anyways since app servers create a thread for each call. I don't think that will in anyways result in concurrency issues but it might have performance drawbacks and at the same time roll backs might not be very reliable but this all depends on the sequence of method calls and it will be case by case. I do suggest you stick to the threadlocal solution.

Umm, one last thought: what happens if you call session.flush at the end of the first step?



Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 08, 2008 3:49 pm 
Newbie

Joined: Mon Apr 07, 2008 1:32 pm
Posts: 7
Hi Farzad,

Keeping the session as 'threadLocal', I am unable to use transaction_read_uncommitted, since the database complains

Code:
Caused by: java.sql.SQLException: READ_COMMITTED and SERIALIZABLE are the only valid transaction levels


Actually, I realised that I haven't mentioned that I'm working with two session factories (since I need to update two different Oracle schemas).

I've tried flushing prior at the end of the create method, but to no avail.

What performance drawbacks would I incur if the session was not marked as threadLocal? and rollbacks too?

Thanks,

Gavin


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 08, 2008 9:10 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
I should have guessed you are working with Oracle. It makes a lot more sense now. Oracle has a different approach when it comes to concurrency. Basically, it does not use shared locks of any kind (might be a BS since I am no Oracle person) but it uses multiversioning and therefore it only supports two isolation levels. In Oracle, a query has access to snapshot of data at the point it starts so if by any means the first transaction is delayed and the second step kicks in then it won't see the modified data and it won't be locked either, so it will read the old data and that's pretty much what is happening in your case. Well, at this point the question is why the second step starts before the transaction in the first step is finished. I am guessing this should have something to do with your app server. What app server are you using?


As for performance concers, it will be very likely that you will load data multiple times because new sessions do not have the data that is already loaded. Also multiple sessions will sync with transaction manager and they will update caches separately and that will cause excessive cache synchronization if a distributed solution is used. As for rollback concerns I think I messed up here a little bit. I should have said data consistency. The thing is that imagine you have two sessions one reads A and the code modifies A. so now we have a modified version of A that is not turned into an update statement yet since this happens when transaction callback methods are called. The other session read A again but since no update has been sent to database the second session get the original value and that something with it. It's rather heuristic here which session will reflect the changes on database but chances are one overwrites the other one's changes.



Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 09, 2008 10:40 am 
Newbie

Joined: Mon Apr 07, 2008 1:32 pm
Posts: 7
farzad wrote:
I should have guessed you are working with Oracle. It makes a lot more sense now. Oracle has a different approach when it comes to concurrency. Basically, it does not use shared locks of any kind (might be a BS since I am no Oracle person) but it uses multiversioning and therefore it only supports two isolation levels. In Oracle, a query has access to snapshot of data at the point it starts so if by any means the first transaction is delayed and the second step kicks in then it won't see the modified data and it won't be locked either, so it will read the old data and that's pretty much what is happening in your case. Well, at this point the question is why the second step starts before the transaction in the first step is finished. I am guessing this should have something to do with your app server. What app server are you using?


As for performance concers, it will be very likely that you will load data multiple times because new sessions do not have the data that is already loaded. Also multiple sessions will sync with transaction manager and they will update caches separately and that will cause excessive cache synchronization if a distributed solution is used. As for rollback concerns I think I messed up here a little bit. I should have said data consistency. The thing is that imagine you have two sessions one reads A and the code modifies A. so now we have a modified version of A that is not turned into an update statement yet since this happens when transaction callback methods are called. The other session read A again but since no update has been sent to database the second session get the original value and that something with it. It's rather heuristic here which session will reflect the changes on database but chances are one overwrites the other one's changes.



Farzad-


Thanks again Farzad!

Explicitly setting the starting and committing the Hibernate transactions is the solution that works, if the sessions remain threadLocal.

In that case I would have to ditch CMT, which I would really prefer.

Gavin


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 09, 2008 11:35 am 
Newbie

Joined: Mon Apr 07, 2008 1:32 pm
Posts: 7
Just to add, if the CMT creates a new session for every method call (essentially a thread), I don't see the difference in assigning a session as threadLocal?

Since other threads (i.e. method calls) would have independent sessions anyways.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 09, 2008 11:37 am 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
It depends how many times you call HibernateUtil.getCurrentSession() (or whatever that gives you a session). There is no difference if it is called only once.



Farzad-


Top
 Profile  
 
 Post subject: CMT doesnot rollback
PostPosted: Tue Sep 23, 2008 6:07 pm 
Newbie

Joined: Mon Sep 15, 2008 8:11 pm
Posts: 5
Hi Farzad,

Please let me know whats wrong with my settings. CMT doesnot rollback hibernate Tx.

Details
--------
I'm using hibernate 3.0 , weblogic 9.2, EJB 2.x, Oracle9i. I'm trying to implement a transaction rollback mechanism in a project. But the transaction does not rollback. Here are my configurations:

hibernate.cfg.xml
---------------------
<property name="transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
<property name="transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="show_sql">false</property>
<property name="jdbc.batch_size">30</property>
<property name="hibernate.jdbc.batch_versioned_data">true</property>
<!-- new addition -->
<property name ="jndi.class">weblogic.jndi.WLInitialContextFactory</property>
<property name="current_session_context_class">thread</property>
.............

Flow
------
SLB1 is the business interface which has business methods with "Required" as transaction attribute.
Business delegate is also a SLB with Tx attribute as "Required".

Business delegate invokes the corresponding some other business interface's business method.

POJO does the CRUD operations with hibernate API's

frontend() -> BusinessDelegate().delegate() -> SLB1.execute() -> POJO.updateDB()

Pojo.update(Object obj)
-----------------
try {
// open session
// session.saveorUpdate(obj);
// session.flush();
} catch (HibernateException e) {
// log exception
throw e;
} finally {
closeSession();
}


SLB1.execute()
-------------------
try {
// call some local business method m1 - "select query"
// call PoJo.update(obj);
Breakpoint >>>>>> // call some local business method m2 - "select query"
} Catch(Exception e) {
// log exception
// throw exception to business delegate
}

Business delegate.delegate()
--------------------------------
try {
// call corresponding SLB1.execute() method
catch(Application exception) {
sessionctx.setRollbackOnly();
// throw exception to front end
}

I tried to test the rollback mechanism. Added a breakpoint using eclipse after the update method call in SLB1.execute method. On reaching the breakpoint, i made the application server down (shutdown). Then when i checking the database, the object is modified.

Don't know what i'm missing. Can you please help me in fixing this issue ?

Thanks in advance


Top
 Profile  
 
 Post subject: Re: CMT doesnot rollback
PostPosted: Wed Sep 24, 2008 12:53 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
This is a rather complicated test. What I suggest you do is first don't close the hibernate session. Hibernate sessions are closed automatically when the active transaction ends. In any events, the reason I say this is a complicated test is that when there is no app server there is no rollback mechanism and I do not know what happens if the transaction is a persistent one, which means when the next time you start the server it should roll back or something. Could you simply fake an error first and see how the rollback works and then look into the app server failure case?


Farzad-

jpa wrote:
Hi Farzad,

Please let me know whats wrong with my settings. CMT doesnot rollback hibernate Tx.

Details
--------
I'm using hibernate 3.0 , weblogic 9.2, EJB 2.x, Oracle9i. I'm trying to implement a transaction rollback mechanism in a project. But the transaction does not rollback. Here are my configurations:

hibernate.cfg.xml
---------------------
<property name="transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
<property name="transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="show_sql">false</property>
<property name="jdbc.batch_size">30</property>
<property name="hibernate.jdbc.batch_versioned_data">true</property>
<!-- new addition -->
<property name ="jndi.class">weblogic.jndi.WLInitialContextFactory</property>
<property name="current_session_context_class">thread</property>
.............

Flow
------
SLB1 is the business interface which has business methods with "Required" as transaction attribute.
Business delegate is also a SLB with Tx attribute as "Required".

Business delegate invokes the corresponding some other business interface's business method.

POJO does the CRUD operations with hibernate API's

frontend() -> BusinessDelegate().delegate() -> SLB1.execute() -> POJO.updateDB()

Pojo.update(Object obj)
-----------------
try {
// open session
// session.saveorUpdate(obj);
// session.flush();
} catch (HibernateException e) {
// log exception
throw e;
} finally {
closeSession();
}


SLB1.execute()
-------------------
try {
// call some local business method m1 - "select query"
// call PoJo.update(obj);
Breakpoint >>>>>> // call some local business method m2 - "select query"
} Catch(Exception e) {
// log exception
// throw exception to business delegate
}

Business delegate.delegate()
--------------------------------
try {
// call corresponding SLB1.execute() method
catch(Application exception) {
sessionctx.setRollbackOnly();
// throw exception to front end
}

I tried to test the rollback mechanism. Added a breakpoint using eclipse after the update method call in SLB1.execute method. On reaching the breakpoint, i made the application server down (shutdown). Then when i checking the database, the object is modified.

Don't know what i'm missing. Can you please help me in fixing this issue ?

Thanks in advance


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 24, 2008 3:14 pm 
Newbie

Joined: Mon Sep 15, 2008 8:11 pm
Posts: 5
I tried adding two lines of code to throw NullPointerException (lines 3,4).
When executing the method, TransactionRolledBackException is thrown correctly. But the modifications does not seem to be rolledback in database.
When i checked the database, the object operated on 'update' method is modified.

SLB1.execute()
-------------------
try {
//1. call some local business method m1 - "select query"
// 2. call PoJo.update(obj);
// 3. String a = null;
// 4. a.toString();
// 5. call some local business method m2 - "select query"
} Catch(Exception e) {
// log exception
// throw exception to business delegate
}

Anyother inputs on this issue ?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 24, 2008 3:14 pm 
Newbie

Joined: Mon Sep 15, 2008 8:11 pm
Posts: 5
I tried adding two lines of code to throw NullPointerException (lines 3,4).
When executing the method, TransactionRolledBackException is thrown correctly. But the modifications does not seem to be rolledback in database.
When i checked the database, the object operated on 'update' method is modified.

SLB1.execute()
-------------------
try {
//1. call some local business method m1 - "select query"
// 2. call PoJo.update(obj);
// 3. String a = null;
// 4. a.toString();

// 5. call some local business method m2 - "select query"
} Catch(Exception e) {
// log exception
// throw exception to business delegate
}

Note: methods m1, update and m2 open three hibernate sessions separately and closes it. Update method alone use session.flush().
Anyother inputs on this issue ?


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