db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Armin Waibel" <ar...@code-au-lait.de>
Subject Re: repost, RE: how to implement a TwoLevelCache
Date Fri, 19 Sep 2003 17:57:08 GMT
Hi,

think it would be great to have a two-level
cache in the kernel api.

> > The cache is supposed to work in an environment where all
> > database clients are in the same VM.  There is one global cache
> > that is always consistent with the data in the database.  
> > Besides, there is one cache for each broker.
> > 
> > References to objects in the global cache are never passed to
> > the application.  When objects enter or leave the global cache,
> > they are cloned. 
....
> > cache strategy.  What do you think?  Has anyone tried something 
> > similar?

Some weeks ago I started to implement a ObjectCache
in a similar way but I'm become stuck with the cloning
stuff.
Think the caching handling in OTM is also compareable with
your proposal. All objects in OTM were cloned (using
ObjectCopyStrategy interface implementations)
except objects with write lock (hope I tell the truth).

I agree Thomas that the cloning of objects is evil.
E.g. say object A has a reference using proxy, the real object
is materialized but the real object itself is not serializeable but
has a clone/copy method ... ok, this can be solved use writeObject/
readObject methods in IndirectionHandler or declare real subject
as transient.
Or object A has a collection of B objects. For A we use serialization
as copy strategy but the B objects use another copy strategy ....

On the other hand with current implementation and
a global ObjectCache we have
problems with dirty reads from cache, corrupt objects in
cache after rollback ....

So I don't know what's the smartest way to go.

regards,
Armin

----- Original Message ----- 
From: <oliver.matz@ppi.de>
To: <ojb-dev@db.apache.org>
Sent: Friday, September 19, 2003 5:11 PM
Subject: repost, RE: how to implement a TwoLevelCache


> Hello,
> 
> I am sorry again if I am pedantic. But since Armin
> just refactored the cache interface, I simply would like
> to remind you of my experiences with this two-level
> cache and the cloning/proxying issues related to it.
> (Please see below for what I wrote then.)
> 
> If we want to ship such a two-level cache, I can contribute
> my work, but it would require further refactoring to make
> it nice.
> 
> It is probably something we do not want to do before 
> 1.0.0 is final.
> 
> regards,
>   Olli
> 
> > -----Original Message-----
> > From: oliver.matz@ppi.de [mailto:oliver.matz@ppi.de]
> > Sent: Tuesday, June 17, 2003 10:24 AM
> > To: ojb-dev@db.apache.org
> > Subject: how to implement a TwoLevelCache, was: RE: caching 
> > enhancements
> > 
> > 
> > Hello,
> > 
> > I would like to share some experiences with you.
> > 
> > > -----Original Message-----
> > > 
> > > Caching between client interfaces: locking and cloning
> > > ------------------------------------------------------
> > > 
> > > Whenever a persistence manager would use an object that was 
> > > seen before by a different persistence manager, this object 
> > > could wear dirty data if simply the reference would be used. 
> > > Check out this example:
> > > 
> > > 2002-12-24 08:34pm      PM1 starts a transaction
> > > 2002-12-24 08:35pm      PM1 loads object "reindeer3" from the 
> > > database, with
> > >                         state "tired"
> > > 2002-12-24 08:36pm      PM2 starts a transaction
> > > 2002-12-24 08:37pm      PM2 searches for "reindeer3" and gets 
> > > a reference to
> > >                         the "reindeer2" used by PM1
> > > 2002-12-24 08:38pm      PM1 feeds "reindeer3" and changes 
> > > it's state to
> > >                         "christmas ready"
> > > 2002-12-24 08:39pm      PM2 sets the state for "reindeer3" to 
> > > "sleeping" in
> > >                         order to make sure it is ready for 
> > 2002-12-25
> > > 
> > > You know what? If both PMs would commit now, both would 
> > > update a "sleeping" state for the reindeer. To find a 
> > > way out of this, at least three solutions are open to be 
> > > implemented:
> > > 
> > > - Make sure PM2 gets a different copy of reindeer3 - by 
> > >   CLONING the reindeer from the cache 
> > > - Make sure PM2 gets a different copy of reindeer3 - by 
> > >   materializing the reindeer again from the database
> > > - Do not allow using reindeer3 multiple times :(
> > 
> > > [thma] I'm not a frient of this cloning business. I know the 
> > > JDORI simply use different cache instances for all 
> > > PersistenceManagers. Those caches are strictly separated and 
> > > will be emptied at transaction end.
> > > 
> > > IMO that's all that is needed.
> > > 
> > > I know that TopLink got in serious trouble with their cloning 
> > 
> > Thomas, can you tell us more about these troubles?
> > 
> > > cache implementation. A lot of user complained. It's not that 
> > > easy to implement. And I don't know if it is worth the effort.
> > > Needs more discussion. [/thma]
> > 
> > O.K., I would like to continue that discussion.
> > 
> > I have tried to implement a class TwoLevelBrokerCache that 
> > implements ObjectCache.  The idea is as follows:
> > 
> > The cache is supposed to work in an environment where all
> > database clients are in the same VM.  There is one global cache
> > that is always consistent with the data in the database.  
> > Besides, there is one cache for each broker.
> > 
> > References to objects in the global cache are never passed to
> > the application.  When objects enter or leave the global cache,
> > they are cloned.  (In the original posting, there is a section 
> > on how to do that cloning, but let us not worry about that.
> > In my situtation, the persistence-capable classes provide a method
> > cacheClone() that does the job).
> > 
> > When an object is inserted in the per-broker-cache, a clone of it
> > is inserted into the global cache.
> > 
> > When the transactin terminates, the per-broker-cache gets cleared.
> > 
> > When an object is lookup up in the cache, we first look into the
> > per-broker-cache and then, if that fails, in the global cache.
> > 
> > I bet the idea is so obvious that other users must have done
> > this before?!
> > 
> > Here are my experiences:
> > 
> > (1) Inside PersistenceBrokerImpl.getDBObject(), the method 
> >     ObjectCache.cache(oid, newObj) is called fairly early - 
> >     namely before newObj's references and collections 
> >     are initialized.  
> >     (This is to be able to handle cyclic references.)
> >     If we clone the object inside ObjectCache.cache(..), then
> >     the clone has uninitialized references and collections.
> > 
> > (2) In order to cope with (1), I would like to initialize
> >     those references and collections with suitable proxies.
> >     However, I had to cut-and-paste and adapt that code from 
> >     PersistenceBrokerImpl because it is hidden in private 
> >     methods.
> > 
> > (3) When testing the implementation, I use two brokers in the 
> >     same thread.  I encountered the PersistenceBrokerThreadMapping.
> >     I had not known before that the concept of a Thread's current
> >     broker is present in the PB API.  I needed to call 
> >      PersistenceBrokerThreadMapping.setCurrentPersistenceBroker
> >     in order to to mix up the two per-broker-caches when traversing
> >     references.
> > 
> > It seems that the current API is not optimal for that two-level 
> > cache strategy.  What do you think?  Has anyone tried something 
> > similar?
> > 
> > I would expect that a clever caching strategy can give a high 
> > perfomance gain, so almost any effort is worth it.
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-dev-help@db.apache.org
> 
> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message