Class PutFromLoadValidator
- java.lang.Object
-
- org.infinispan.hibernate.cache.commons.access.PutFromLoadValidator
-
public class PutFromLoadValidator extends Object
Encapsulates logic to allow aInvalidationCacheAccessDelegate
to determine whether aInvalidationCacheAccessDelegate.putFromLoad(Object, Object, Object, long, Object, boolean)
call should be allowed to update the cache. AputFromLoad
has the potential to store stale data, since the data may have been removed from the database and the cache between the time when the data was read from the database and the actual call toputFromLoad
.The expected usage of this class by a thread that read the cache and did not find data is:
- Call
registerPendingPut(Object, Object, long)
- Read the database
- Call
acquirePutFromLoadLock(Object, Object, long)
- if above returns
null
, the thread should not cache the data; only if above returns instance ofAcquiredLock
, put data in the cache and... - then call
releasePutFromLoadLock(Object, Lock)
The expected usage by a thread that is taking an action such that any pending
putFromLoad
may have stale data and should not cache it is to either call-
beginInvalidatingKey(Object, Object)
(for a single key invalidation) - or
beginInvalidatingRegion()
followed byendInvalidatingRegion()
(for a general invalidation all pending puts)
endInvalidatingKey(Object, Object)
should be called in order to allow further attempts to cache entry.This class also supports the concept of "naked puts", which are calls to
acquirePutFromLoadLock(Object, Object, long)
without a precedingregisterPendingPut(Object, Object, long)
. Besides not acquiring lock inregisterPendingPut(Object, Object, long)
this can happen when collection elements are loaded after the collection has not been found in the cache, where the elements don't have their own table but can be listed as 'select ... from Element where collection_id = ...'. Naked puts are handled according to txTimestamp obtained by callingRegionFactory.nextTimestamp()
before the transaction is started. The timestamp is compared with timestamp of last invalidation end time and the write to the cache is denied if it is lower or equal.- Version:
- $Revision: $
- Author:
- Brian Stansberry
- Call
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
PutFromLoadValidator.Lock
Marker for lock acquired inacquirePutFromLoadLock(Object, Object, long)
-
Constructor Summary
Constructors Constructor Description PutFromLoadValidator(org.infinispan.AdvancedCache cache, TimeSource timeSource, org.infinispan.configuration.cache.Configuration pendingPutsConfiguration)
Creates a new put from load validator instance.PutFromLoadValidator(org.infinispan.AdvancedCache cache, TimeSource timeSource, org.infinispan.manager.EmbeddedCacheManager cacheManager, org.infinispan.configuration.cache.Configuration pendingPutsConfiguration)
Creates a new put from load validator instance.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description PutFromLoadValidator.Lock
acquirePutFromLoadLock(Object session, Object key, long txTimestamp)
Acquire a lock giving the calling thread the right to put data in the cache for the given key.static void
addToCache(org.infinispan.AdvancedCache cache, PutFromLoadValidator validator)
Besides the call from constructor, this should be called only from tests when mocking the validator.boolean
beginInvalidatingKey(Object lockOwner, Object key)
Invalidates anypreviously registered pending puts
and disables further registrations ensuring a subsequent call toacquirePutFromLoadLock(Object, Object, long)
will returnfalse
.boolean
beginInvalidatingRegion()
Invalidates allpreviously registered pending puts
ensuring a subsequent call toacquirePutFromLoadLock(Object, Object, long)
will returnfalse
.boolean
beginInvalidatingWithPFER(Object lockOwner, Object key, Object valueForPFER)
void
destroy()
boolean
endInvalidatingKey(Object lockOwner, Object key)
boolean
endInvalidatingKey(Object lockOwner, Object key, boolean doPFER)
Called after the transaction completes, allowing caching of entries.void
endInvalidatingRegion()
Called when the region invalidation is finished.void
registerPendingPut(Object session, Object key, long txTimestamp)
Notifies this validator that it is expected that a database read followed by a subsequentacquirePutFromLoadLock(Object, Object, long)
call will occur.void
releasePutFromLoadLock(Object key, PutFromLoadValidator.Lock lock)
Releases the lock previously obtained by a call toacquirePutFromLoadLock(Object, Object, long)
.static PutFromLoadValidator
removeFromCache(org.infinispan.AdvancedCache cache)
This methods should be called only from tests; it removes existing validator from the cache structures in order to replace it with new one.void
removePendingPutsCache()
-
-
-
Constructor Detail
-
PutFromLoadValidator
public PutFromLoadValidator(org.infinispan.AdvancedCache cache, TimeSource timeSource, org.infinispan.configuration.cache.Configuration pendingPutsConfiguration)
Creates a new put from load validator instance.- Parameters:
pendingPutsConfiguration
-cache
- Cache instance on which to store pending put information.
-
PutFromLoadValidator
public PutFromLoadValidator(org.infinispan.AdvancedCache cache, TimeSource timeSource, org.infinispan.manager.EmbeddedCacheManager cacheManager, org.infinispan.configuration.cache.Configuration pendingPutsConfiguration)
Creates a new put from load validator instance.- Parameters:
cache
- Cache instance on which to store pending put information.timeSource
-cacheManager
- where to find a cache to store pending put informationpendingPutsConfiguration
-
-
-
Method Detail
-
addToCache
public static void addToCache(org.infinispan.AdvancedCache cache, PutFromLoadValidator validator)
Besides the call from constructor, this should be called only from tests when mocking the validator.
-
removeFromCache
public static PutFromLoadValidator removeFromCache(org.infinispan.AdvancedCache cache)
This methods should be called only from tests; it removes existing validator from the cache structures in order to replace it with new one.- Parameters:
cache
-
-
destroy
public void destroy()
-
acquirePutFromLoadLock
public PutFromLoadValidator.Lock acquirePutFromLoadLock(Object session, Object key, long txTimestamp)
Acquire a lock giving the calling thread the right to put data in the cache for the given key.NOTE: A call to this method that returns
true
should always be matched with a call toreleasePutFromLoadLock(Object, Lock)
.- Parameters:
session
-key
- the keytxTimestamp
-- Returns:
AcquiredLock
if the lock is acquired and the cache put can proceed;null
if the data should not be cached
-
releasePutFromLoadLock
public void releasePutFromLoadLock(Object key, PutFromLoadValidator.Lock lock)
Releases the lock previously obtained by a call toacquirePutFromLoadLock(Object, Object, long)
.- Parameters:
key
- the key
-
beginInvalidatingRegion
public boolean beginInvalidatingRegion()
Invalidates allpreviously registered pending puts
ensuring a subsequent call toacquirePutFromLoadLock(Object, Object, long)
will returnfalse
.This method will block until any concurrent thread that has
acquired the putFromLoad lock
for the any key has released the lock. This allows the caller to be certain the putFromLoad will not execute after this method returns, possibly caching stale data.- Returns:
true
if the invalidation was successful;false
if a problem occurred (which the caller should treat as an exception condition)
-
endInvalidatingRegion
public void endInvalidatingRegion()
Called when the region invalidation is finished.
-
registerPendingPut
public void registerPendingPut(Object session, Object key, long txTimestamp)
Notifies this validator that it is expected that a database read followed by a subsequentacquirePutFromLoadLock(Object, Object, long)
call will occur. The intent is this method would be called following a cache miss wherein it is expected that a database read plus cache put will occur. Calling this method allows the validator to treat the subsequentacquirePutFromLoadLock
as if the database read occurred when this method was invoked. This allows the validator to compare the timestamp of this call against the timestamp of subsequent removal notifications.- Parameters:
session
-key
- key that will be used for subsequent cache puttxTimestamp
-
-
beginInvalidatingKey
public boolean beginInvalidatingKey(Object lockOwner, Object key)
Invalidates anypreviously registered pending puts
and disables further registrations ensuring a subsequent call toacquirePutFromLoadLock(Object, Object, long)
will returnfalse
.This method will block until any concurrent thread that has
After this transaction completes,acquired the putFromLoad lock
for the given key has released the lock. This allows the caller to be certain the putFromLoad will not execute after this method returns, possibly caching stale data.endInvalidatingKey(Object, Object)
needs to be called }- Parameters:
key
- key identifying data whose pending puts should be invalidated- Returns:
true
if the invalidation was successful;false
if a problem occurred (which the caller should treat as an exception condition)
-
beginInvalidatingWithPFER
public boolean beginInvalidatingWithPFER(Object lockOwner, Object key, Object valueForPFER)
-
endInvalidatingKey
public boolean endInvalidatingKey(Object lockOwner, Object key, boolean doPFER)
Called after the transaction completes, allowing caching of entries. It is possible that this method is called without previous invocation ofbeginInvalidatingKey(Object, Object)
, then it should be a no-op.- Parameters:
lockOwner
- owner of the invalidation - transaction or threadkey
-- Returns:
-
removePendingPutsCache
public void removePendingPutsCache()
-
-