Cache-aside and loader/writer contracts
Latest stable Based on Bluetape4k release 1.11.0
The caller owns cache-aside
Section titled “The caller owns cache-aside”With cache-aside, the service or repository observes a miss, reads source data, and puts the result into the cache.
fun findProduct(id: Long): Product { productCache.get(id)?.let { return it } return productRepository.find(id).also { productCache.put(id, it) }}The first request reads the database. The cache API does not know the source store, so the caller owns update and invalidation after a write transaction.
Concurrent misses in getOrPut
Section titled “Concurrent misses in getOrPut”The JCache getOrPut extension gets the key, evaluates a supplier on a miss, and calls putIfAbsent. Concurrent misses may evaluate the supplier more than once. The final return value is aligned with the first cached value, but external work is not deduplicated.
val product = cache.getOrPut(id) { productRepository.find(id) }Use a same-key memoizer or a provider loading cache when duplicate database work is not acceptable.
JCache read-through
Section titled “JCache read-through”JCache read-through exists when a CacheLoader factory is registered with isReadThrough=true. The cacheLoader() extension in cache-core merely adapts another cache; supply a repository-backed loader for database reads.
val config = jcacheConfigurationOf<Long, Product>( cacheLoaderFactory = FactoryBuilder.factoryOf(ProductLoader(productRepository)), isReadThrough = true,)Test provider exception wrapping and null handling because the loader now owns the miss path.
The exact scope of write-through
Section titled “The exact scope of write-through”JCache write-through requires a CacheWriter factory and isWriteThrough=true, with cache changes invoking the backing store. The cache.cacheWriter() helper delegates to that cache’s own put and remove; it is not a database writer.
A Near Cache put similarly updates local and remote cache tiers. It does not update a database or Exposed table, so it is not persistence write-through.
Partial failure around source data
Section titled “Partial failure around source data”Writing source data first can leave a stale entry when invalidation fails. Writing the cache first can expose data that never committed. Without a transaction across both systems, choose an explicit rule:
- write source data, then invalidate, and bound stale time with a short TTL;
- retry invalidation through an outbox or event and measure delay;
- use a repository design such as
JdbcCacheRepositorythat owns loader, writer, and persistence boundaries.