-->
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.  [ 11 posts ] 
Author Message
 Post subject: Still Obtaining "old" data from a session after &q
PostPosted: Fri Feb 27, 2004 3:54 am 
Beginner
Beginner

Joined: Thu Dec 04, 2003 3:47 am
Posts: 31
Location: Hong Kong
I have several threads, each open a session and gain access to the same data set. One thread t1 changes the data and commits the change. (the change has been persisted and visual from the DB) Another thread t2 loads the same data record the print it out. However, I find that the data retrieved contains "old" data. I suppose it is because the data is read from the cache as t2 load the data previously. So I tried to use the refresh method from the session, still the "old" data is read. I further use the LockMode.READ in the refresh as the following, but the result is the same.

Code:
ThreadSessionHolder.get().refresh(thedataobject, LockMode.READ);


From the API doc, refresh is supposed to re-read the data from the database, and LockMode.READ "were read from the database in the current transaction, rather than being pulled from a cache." (Or do i misunderstand?)

Anyway, I try to do the update directly on the DB by SQL, and the session still read old data even using "refresh". I have tried to glance through Hibernate documentation and FAQ, but cannot find similar problem. Could anyone provide some suggestions how to solve such problem?


Top
 Profile  
 
 Post subject: Still Obtaining "old" data from a session after re
PostPosted: Fri Feb 27, 2004 3:55 am 
Beginner
Beginner

Joined: Thu Dec 04, 2003 3:47 am
Posts: 31
Location: Hong Kong
Sorry, forgot to mention, i'm using hibernate 2.0.3 and MySQL db v4.0.12


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2004 7:21 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
I think you are not closing your sessions where you should close it. If you reuse an old session, the data will be read from the session level cache. You should close the session after every request, or evict the session when you want to reload your data from the db.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2004 8:17 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
as i can see, you're using threadlocal session:
- are you sure you're cleaning the "threadlocal" on each request ?
- "I try to do the update directly on the DB by SQL" are you sure this sql has been followed by a commit?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2004 8:44 am 
Beginner
Beginner

Joined: Thu Dec 04, 2003 3:47 am
Posts: 31
Location: Hong Kong
thx for gloeglm and delpouve reply

1. Actually I'm using JMS and I create and then close the session for each message handler when it starts / finishes its execution, although there may be some bugs inside my cleaning up code which does not actually close the session in some cases. However, what I'm more concern is that even i'm using an old session should the session.refresh force hibernate reading the data from DB instead of cache? or is there any correct way to enforce retrieving data from DB or evict the session?

2. Yes, i'm using threadlocal and I did the cleanning work (although i'm not sure it's bug free)

3. For my "update directly on the DB by SQL" testing, I turn the autocommit on. So I expect the updates should have been persisted.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2004 8:51 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
I am pretty sure you have some bug in your session management. Check if you really use a fresh session every time. (use a debugger or something). Session.refresh(object) should reread the object from the database, session.evict() clears the whole session cache. If session.refresh() does not read the data from the database, I am sure you have some wrong transaction handling.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2004 9:02 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
same as gloeglm, if you can update to latest version of hibernate, and use session.clear(); by doing this you'll have an "empty" session


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2004 9:05 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Ah yes, delpouve is right of course, session.clear() clears the whole session, session.evict(object) just removes one object from the session cache.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 29, 2004 11:29 pm 
Beginner
Beginner

Joined: Thu Dec 04, 2003 3:47 am
Posts: 31
Location: Hong Kong
Sorry that I still face the same problem after trying different solution.

1. I checked my session management. I print the session before I do the load in the thread that is used to get the dataobject from Hibernate, I find that the printed value is different everytime (so I suppose the session management is ok, that is the thread close the session everytime when it finished load, and create a new session when it do the load), the session should be the fresh one.

2. I tried session.refresh() and session.evict(), both gives the same result. The thread reading the dataobject still return the old values

3. For transaction handling, for my update thread, I begin the transaction just before calling the session.update(), and commit it immediately if no excpetion is thrown. So I suppose the updating thread should have committed the change, and the fact is all other sessions in the mysql can read the updated value.

4. I even tried the following 2 scenario.
a. I start hibernate, use hiberante to load the dataobject, then directly in mysql prompt do the update on that dataobject (and do the commit), and use hibernate (another session) to load the dataobject again, it reads old values.

b. I start hibernate, then directly in mysql prompt do the update, and use hibernate to load the dataobject, it reads updated value.

so the only conclusion i can make is if hibernate does not load the dataobject before, it can read the updated values. If it has loaded before, it keeps reading old values.


I really can't think of other ways to try or find out what the problem is. I hope I can have more understanding on hibernate cache handling. So are there any "common" cache behind the session cache? I think this should be my setting problem (although I have tried to debug the things that may cause the problem, including session/transaction handling etc.), since this is just very common operations and I don't see others have such problem. Anyone has any ideas that can point where my problem is, pls suggest. Many Thank!


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 29, 2004 11:49 pm 
Beginner
Beginner

Joined: Thu Dec 04, 2003 3:47 am
Posts: 31
Location: Hong Kong
one more finding

i use different fresh session for each update, load

i have the following scenario (in sequence)

1. original value in DB for record A is x
2. update from x to y
3. load, value read is x
4. update from y to z
5. load, value read is y
6. update from z to a
7. load. value read is z
...

so the read always read the value before the last update. However, from the db, i can always see the most updated value.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 01, 2004 2:33 am 
Beginner
Beginner

Joined: Thu Dec 04, 2003 3:47 am
Posts: 31
Location: Hong Kong
Finally, I find the problem, but still have something I don't understand

The problem is about transaction isolation level. Since the table type is set to be INNODB for the mysql db (since i want to support transaction) and the default isolation level for INNODB is REPEATABLE READ

My understanding of REPEATABLE READ is
In a transaction, if I read a record, no matter how many times I re-read the record within the transaction (even it has been updated by other transaction), it reads the same value.

So when my reading thread reads the value, even the updating thread updates the record, when the next time the reading thread re-read the value, it read the old value.

So after I change the global transaction isolation level as READ_COMMITTED or SERIALIZABLE, the reading thread can read the updated value. Problem seems to be solved!

However, I would like to get more understanding. For my reading thread, I never explicitly start any transaction. Since I use a new fresh session for every read, so even if the transaction is started within the session, it should be ended when the session is closed after reading the value


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