db-jdo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Matthew T. Adams" <matthew.ad...@xcalia.com>
Subject RE: Cache invalidation
Date Tue, 07 Feb 2006 16:38:08 GMT
I'm for the change; it makes the API more self-documenting.


>-----Original Message-----
>From: Craig.Russell@Sun.COM [mailto:Craig.Russell@Sun.COM] 
>Sent: Monday, February 06, 2006 4:00 PM
>Cc: JDO Expert Group; Apache JDO project
>Subject: Re: Cache invalidation
>For the record,
>I'm not opposed to name changes as long as they are consistent and  
>there is time in the release cycle to implement (trivial). I think  
>the proposal is to change all of the names in the DataStoreCache API  
>to include "ById".
>Do we care about any users who would be affected?
>On Feb 6, 2006, at 2:53 PM, Wes Biggs wrote:
>> I agree that it would be nice to change the method signatures to  
>> "evictById" for those that take OIDs in order to avoid confusion.
>> To clarify what I mean about persistent nontransactional objects,  
>> see section 5.6.1 of the spec:
>> "A persistent-nontransactional instance transitions to persistent- 
>> clean if any managed field
>> is accessed when a datastore transaction is in progress. The state  
>> of the instance in memory
>> is discarded and the state is loaded from the datastore."
>> If you are running with an optimistic transaction instead, you'll  
>> get an optimistic verification exception at commit time.  So I  
>> guess it is possible to read stale data from the instance in the PM  
>> cache under a couple of scenarios:
>> 1. Reading previously loaded fields of a P-NT instance outside of a  
>> transaction.
>> 2. Reading previously loaded fields of a P-NT instance inside an  
>> optimistic transaction.
>> In these cases, I think you're right that it would be necessary to  
>> hollow the instances in order to be absolutely sure that no stale  
>> data is read after a L2 cache evict().
>> On the other hand, if you're in an optimistic transaction, don't  
>> you want to retain the previously read values (they represent the  
>> ACID guarantee from the optimistic transaction)?  So the only case  
>> where it might make sense to me is #1 above, and that seems  
>> debatable to me.  Do most people using P-NT objects expect them to  
>> be consistent with the L2 cache at all times?  Or are they expected  
>> to act like a limited form of an optimistic transaction?
>> I don't have a strong opinion about this, I'm just trying to fully  
>> articulate the question.
>> Wes
>> Joerg von Frantzius wrote:
>>> Hi Wes,
>>> thanks for your answer, please see my comments below.
>>> Wesley Biggs schrieb:
>>>> Joerg von Frantzius wrote:
>>>>> The problem here is that either evict() accepts only PC objects,  
>>>>> not object ids, so we have to call PM.getObjectById()  
>>>>> beforehand. If no object for that id was present, we're  
>>>>> instantiating a hollow object here only to discard it  
>>>>> afterwards, that's not very effective.
>>>> I'm not quite parsing your "either" here, sorry.  But  
>>>> DataStoreCache.evict() accepts object IDs.  I'm not sure I see  
>>>> the necessity of calling PM.evict() as well, unless you have some  
>>>> particularly long-lived transactions.
>>> We're doing nontransactional reads on long-living objects, so I  
>>> guessed we needed to call PM.evict() to avoid accessing stale  
>>> field data.
>>> You're of course right about DatastoreCache.evict() accepting IDs,  
>>> thanks for pointing that out. I had just seen the same method  
>>> signature, and so I assumed the parameter semantics also being the  
>>> same.
>>> Calling it evictById() probably would be less misleading, even  
>>> more so as a mistake here won't show up immediately. Also, if you  
>>> only have a jar without sourcecode, the signatures are absolutely  
>>> indistinguishable (Which of course is not an excuse for not having  
>>> read the spec thoroughly enough ;)
>>>>> As we really want cache invalidation here, not eviction, this is  
>>>>> even worse. For this purpose, it would be far more convenient to  
>>>>> have some method like invalidateCachesFor(Object id) on  
>>>>> PersistenceManagerFactory.
>>>> That's the intention of DataStoreCache.evict().  The semantics  
>>>> are different than PM.evict().
>>> Only now I start understanding that I was misled by the word evict 
>>> () for the L2-cache: as the user never gets hold of an L2 cache  
>>> object anyway (a L1-cache object will be created for that), he  
>>> shouldn't need to care whether the L2 cache internally needs to  
>>> throw away (evict) some object in order to invalidate cached  
>>> state. Spec says "/The evict methods are hints to the  
>>> implementation that the instances referred to by the object ids  
>>> are stale and should be evicted from the cache./" It might be nit- 
>>> picking, but I think it would be clearer if the method was called  
>>> invalidateByÍd(), which would be natural for some cache interface,  
>>> and if the explanation said "/that the object state referred to by  
>>> the object ids should be discarded/"
>>> Also, the spec doesn't say anything about DatastoreCache.evict()  
>>> having any impact on P-nontrans instances. So I still need to go  
>>> to every PM and evict there as well, which is very inconvenient.
>>> Or does the "evict" row in table 2 for P-nontrans really apply to / 
>>> both /evict() methods, not only PM.evict()!? The RI JPOX isn't  
>>> doing anything like that, by the way.
>>>>> To make our wish complete ;) this method would transition all  
>>>>> non-transactional instances to hollow for that id, for all the  
>>>>> PMs the PMF has given out. All transactional objects with that  
>>>>> id should be transitioned to hollow after their transaction has  
>>>>> completed (either with commit or rollback).
>>>> Persistent nontransactional instances will have to be revalidated  
>>>> against the datastore (or cache thereof) before being re-enlisted  
>>>> in a transaction anyway.  The behavior you mention is a good way  
>>>> to implement that, but it doesn't need to be mandated (hollow is  
>>>> not a user-visible state).
>>> I'm not sure what you mean by mandating here? I'd just like to  
>>> make sure that invalidated non-transactional instances will reload  
>>> state upon next read access, without having to iterate all PMs.  
>>> Also, I'd rather not like a call to PM.getObjectById() afterwards  
>>> returning a new Java object for the same id, which I guess is the  
>>> case after calling PM.evict(PM.getObjectById(id)).
>>> If a method invalidateById() existed, I'd see the sense of evict()  
>>> in releasing the associated memory. evict() currently does two  
>>> things at same time: evicting and transitioning to hollow. For  
>>> (distributed) cache invalidation, I find it sensible to desire  
>>> only the latter.
>>> Regards,
>>> Jörg
>Craig Russell
>Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
>408 276-5638 mailto:Craig.Russell@sun.com
>P.S. A good JDO? O, Gasp!

View raw message