-->
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: Read committed not always maintained in read-write strategy
PostPosted: Tue Jul 26, 2005 10:05 am 
Beginner
Beginner

Joined: Sun Sep 19, 2004 5:02 pm
Posts: 28
Location: Poland
Hibernate version:
2.1.8

I think I've found some cases when read-write cache strategy doesn't maintain read comitted isolation level.

First:
Cached object is updated, then its lock is evicted from cache and session is flushed and cleared. Then updated object is loaded from database and put into the cache (still all in the same transaction). Other transactions can now see this not committed object.

Second:
Some cached object is inserted, then session.flush, and session.clear. Next I load this inserted not committed object from database. It is putted into cache and other transactions can see it.

Third:
Because inserted object is not locked there is a possibility that betwen commit and afterInsert this new inserted object can be deleted/updated by other transactions. When object/lock will be evicted from cache then old or non existent records can be put into cache.

_________________
Lmichasz


Top
 Profile  
 
 Post subject: Re: Read committed not always maintained in read-write strat
PostPosted: Tue Jul 26, 2005 6:22 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Lmichasz wrote:
First:
Cached object is updated, then its lock is evicted from cache and session is flushed and cleared. Then updated object is loaded from database and put into the cache (still all in the same transaction). Other transactions can now see this not committed object.


Yes, this would break isolation.

Lmichasz wrote:
Second:
Some cached object is inserted, then session.flush, and session.clear. Next I load this inserted not committed object from database. It is putted into cache and other transactions can see it.


Basically same case as the first.

I must say, I don't really consider either of the above cases as very important, nor do I think they are solveable. You shouldn't use session.clear() like this, I guess.

Lmichasz wrote:
Third:
Because inserted object is not locked there is a possibility that betwen commit and afterInsert this new inserted object can be deleted/updated by other transactions. When object/lock will be evicted from cache then old or non existent records can be put into cache.


You might be right here too, and I would consider this a bug. Would you please try to produce a runnable test case that demonstrates this problem and submit to JIRA. Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 29, 2005 6:58 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Actually, I checked the code, and your analysis of the third case is incorrect. Old state cannot end up back in the cache, because afterInsert() is a no-op if there is anything else has already been put in the cache at that key.


So, I'm happy with current implementation.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 10, 2005 5:02 pm 
Beginner
Beginner

Joined: Sun Sep 19, 2004 5:02 pm
Posts: 28
Location: Poland
Well in Hiberate 2.1.6 ReadWriteCache.afterInsert() looks as fallows:

public synchronized void afterInsert(Object key, Object value) throws CacheException {
if ( log.isTraceEnabled() ) log.trace("Inserting: " + key);
try {
cache.lock(key);

Lockable lockable = (Lockable) cache.get(key);
if (lockable==null) {
cache.put( key, new Item( value, cache.nextTimestamp() ) );
if ( log.isTraceEnabled() ) log.trace("Inserted: " + key);
}
}
finally {
cache.unlock(key);
}
}

Lets have two transactions A and B.

A inserts one cached object of class X and commits.

B executes completly (with all its afterInsert, afterUpdate, release) between commit of A and afterInsert of A.

B updates object inserted by A and also updates lot of other objects of class X (more than can cache for X contain). So when B is finished, cache for X wouldn't contain object inserted in transaction A.

Lets come back to afterInsert method for transaction A for this inserted object of class X. Now it is invoked and lockable will be null. Object is inserted into cache. Update of B is not visible, cache state is inconsistent with database.


This is very rare scenario but it is possible.

_________________
Lmichasz


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.