cache-as-sor
The cache-as-sor pattern implies using the cache as though it were the primary system-of-record (SOR). The pattern delegates SOR reading and writing activities to the cache, so that application code is absolved of this responsibility.
To implement the cache-as-sor pattern, use a combination of the following read and write patterns:
read-through
write-through or write-behind
Advantages of using the cache-as-sor pattern are:
Less cluttered application code (improved maintainability)
Choice of write-through or write-behind strategies on a per-cache basis (use only configuration)
Allows the cache to solve the "thundering-herd" problem
A disadvantage of using the cache-as-sor pattern is:
Less directly visible code-path
cache-as-sor example
public class MyDataAccessClass
{
private final Ehcache cache;
public MyDataAccessClass(Ehcache cache)
{
cache.registerCacheWriter(new MyCacheWriter());
this.cache = new SelfPopulatingCache(cache);
}
/* read some data - notice the cache is treated as an SOR.
* the application code simply assumes the key will always be available
*/
public V readSomeData(K key)
{
return cache.get(key);
}
/* write some data - notice the cache is treated as an SOR, it is
* the cache's responsibility to write the data to the SOR.
*/
public void writeSomeData(K key, V value)
{
cache.put(new Element(key, value);
}
/**
* Implement the CacheEntryFactory that allows the cache to provide
* the read-through strategy
*/
private class MyCacheEntryFactory implements CacheEntryFactory
{
public Object createEntry(Object key) throws Exception
{
return readDataFromDataStore(key);
}
}
/**
* Implement the CacheWriter interface which allows the cache to provide
* the write-through or write-behind strategy.
*/
private class MyCacheWriter implements CacheWriter
public CacheWriter clone(Ehcache cache) throws CloneNotSupportedException;
{
throw new CloneNotSupportedException();
}
public void init() { }
void dispose() throws CacheException { }
void write(Element element) throws CacheException;
{
writeDataToDataStore(element.getKey(), element.getValue());
}
void writeAll(Collection<Element> elements) throws CacheException
{
for (Element element : elements) {
write(element);
}
}
void delete(CacheEntry entry) throws CacheException
{
deleteDataFromDataStore(element.getKey());
}
void deleteAll(Collection<CacheEntry> entries) throws CacheException
{
for (Element element : elements) {
delete(element);
}
}
}
}